views:

145

answers:

2

I am developing a ASP .Net MVC project but i can't make overload of Index() even when i have defined other method with different no. of parameters & have given proper routing for it . But it doesnot seems to work. So i just want to ask can we make overloaded methods in controller or not?

+5  A: 

Controller actions with the same name are possible on the same controller if they are called with different HTTP verbs. Example:

public ActionResult Index() 
{
    return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(SomeModel model) 
{
   return View();
}

When you call GET /Controller/Index the first action will be invoked and when you call POST /Controller/Index the second action will be invoked.

Darin Dimitrov
@Darin i know this, but what if my both method are with [AcceptVerbs(HttpBerb.Post)] attribute but they differ in no. of parameters is there any way to call them if i can give routing with isIndexContraint for them.
deepesh khatri
A: 

To be more specific, you have to vary it by selection criteria (which might be a verbs change as Darin said, but could also be other selector attributes like NonAction or ActionName). For that matter, you could create your own ActionNameSelectorAttribute derivative to create custom logic indicating when a given method should be used over another.

Update: added code per request.

I am actually creating a sample ActionMethodSelectorAttribute, b/c I couldn't think of a good usecase for just testing on the name that's not already covered by the ActionNameAttribute. Principle is the same either way, though.

public class AllParamsRequiredAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        var paramList = methodInfo.GetParameters().Select(p => p.Name);
        foreach (var p in paramList)
            if (controllerContext.Controller.ValueProvider.GetValue(controllerContext, p) == null) return false;
        return true;
    }
}

Basically, this one just gets the names of the params on the action method that it flags, and tests to make sure that the controller's ValueProvider has at least an attempted value of the same name as each. This obviously only works for simple types and doesn't test to make sure the attempted value can cast properly or anyting; it's nowhere close to a production attribute. Just wanted to show that it's easy and really any logic you can return a bool from can be used.

This could be applied, then as follows:

[AllParamsRequired]
public ViewResult Index(int count){/*... your logic ... */}
public ViewResult Index() {/*... more of your logic ... */}

in this example,and default routing, the url mydomain.com/?count=5 will match the first one, and the url mydomain.com/ will match the second one.

Paul

Paul
@paul: Can you please write the sample code for Creating ActionNameSelectorAttribute derivative to create custom?
deepesh khatri
Sure, added above.
Paul