Can you overload controller methods in ASP.NET MVC

2018-12-31 09:29发布

I'm curious to see if you can overload controller methods in ASP.NET MVC. Whenever I try, I get the error below. The two methods accept different arguments. Is this something that cannot be done?

The current request for action 'MyMethod' on controller type 'MyController' is ambiguous between the following action methods:

16条回答
人气声优
2楼-- · 2018-12-31 09:41

I have faced same issue in my application too. Without Modifiyig any Method information, I have provided [ActionName("SomeMeaningfulName")] on Action head. issue resolved

[ActionName("_EmployeeDetailsByModel")]
        public PartialViewResult _EmployeeDetails(Employee model)
        {
            // Some Operation                
                return PartialView(model);
            }
        }

[ActionName("_EmployeeDetailsByModelWithPagination")]
        public PartialViewResult _EmployeeDetails(Employee model,int Page,int PageSize)
        {

                // Some Operation
                return PartialView(model);

        }
查看更多
浅入江南
3楼-- · 2018-12-31 09:49

To overcome this problem you can write an ActionMethodSelectorAttribute that examines the MethodInfo for each action and compares it to the posted Form values and then rejects any method for which the form values don't match (excluding the button name, of course).

Here's an example:- http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

BUT, this isn't a good idea.

查看更多
低头抚发
4楼-- · 2018-12-31 09:52

Create the base method as virtual

public virtual ActionResult Index()

Create the overridden method as override

public override ActionResult Index()

Edit: This obviously applies only if the override method is in a derived class which appears not to have been the OP's intention.

查看更多
皆成旧梦
5楼-- · 2018-12-31 09:53

I've just come across this question and, even though it's quite old now, it's still very relevant. Ironically, the one correct comment in this thread was posted by a self-confessed beginner in MVC when he wrote the post. Even the ASP.NET docs are not entirely correct. I have a large project and I successfully overload action methods.

If one understands routing, beyond the simple {controller}/{action}/{id} default route pattern, it might be obvious that controller actions can be mapped using any unique pattern. Someone here talked about polymorphism and said: "HTTP does not understand polymorphism", but routing has nothing to do with HTTP. It is, simply put, a mechanism for string pattern matching.

The best way to make this work is to use the routing attributes, for example:

[RoutePrefix("cars/{country:length(3)}")]
public class CarHireController
{
    [Route("{location}/{page:int=1}", Name = "CarHireLocation")]
    public ActionResult Index(string country, string location, int page)
    {
        return Index(country, location, null, page);
    }

    [Route("{location}/{subLocation}/{page:int=1}", Name = "CarHireSubLocation")]
    public ActionResult Index(string country, string location, string subLocation, int page)
    {
        //The main work goes here
    }
}

These actions will take care of urls like /cars/usa/new-york and /cars/usa/texas/dallas, which will map to the first and second Index actions respectively.

Examining this example controller it's evident that it goes beyond the default route pattern mentioned above. The default works well if your url structure exactly matches your code naming conventions, but this is not always the case. Code should be descriptive of the domain, but urls often need to go further because their content should be based on other criteria, such as SEO requirements.

The benefit of the default routing pattern is that it automatically creates unique routes. This is enforced by the compiler since urls will match unique controller types and members. Rolling your own route patterns will require careful thought to ensure uniqueness and that they work.

Important note The one drawback is that using routing to generate urls for overloaded actions does not work when based on an action name, e.g., when using UrlHelper.Action. But it does work if one uses named routes, e.g., UrlHelper.RouteUrl. And using named routes is, according to well respected sources, the way to go anyhow (http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/).

Good luck!

查看更多
梦寄多情
6楼-- · 2018-12-31 09:53

You can use [ActionName("NewActionName")] to use the same method with a different name:

public class HomeController : Controller
{
    public ActionResult GetEmpName()
    {
        return Content("This is the test Message");
    }

    [ActionName("GetEmpWithCode")]
    public ActionResult GetEmpName(string EmpCode)
    {
        return Content("This is the test Messagewith Overloaded");
    }
}
查看更多
萌妹纸的霸气范
7楼-- · 2018-12-31 09:54

Here's something else you could do... you want a method that is able to have a parameter and not.

Why not try this...

public ActionResult Show( string username = null )
{
   ...
}

This has worked for me... and in this one method, you can actually test to see if you have the incoming parameter.


Updated to remove the invalid nullable syntax on string and use a default parameter value.

查看更多
登录 后发表回答