我很好奇你是否可以重载控制器方法在ASP。净MVC。每当我尝试时,都会得到下面的错误。这两个方法接受不同的参数。这是做不到的事情吗?

当前对控制器类型“MyController”上的动作“MyMethod”的请求在以下动作方法之间是不明确的:


当前回答

不,不,不。去试试下面的控制器代码,在这里我们重载了“LoadCustomer”。

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

如果您尝试调用“LoadCustomer”操作,您将得到如下图所示的错误。

多态性是c#编程的一部分,而HTTP是一种协议。HTTP不理解多态性。HTTP工作在概念或URL和URL只能有唯一的名称。因此HTTP不实现多态性。

为了解决这个问题,我们需要使用“ActionName”属性。

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }

        [ActionName("LoadCustomerbyName")]
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

因此,现在如果你调用URL“客户/LoadCustomer”,“LoadCustomer”动作将被调用,URL结构“客户/LoadCustomerByName”,“LoadCustomer(字符串str)”将被调用。

上面的答案我已经从这篇codeproject文章——> MVC动作重载

其他回答

我需要一个过载:

public ActionResult Index(string i);
public ActionResult Index(int groupId, int itemId);

很少有足够的争论,我最终这样做:

public ActionResult Index(string i, int? groupId, int? itemId)
{
    if (!string.IsNullOrWhitespace(i))
    {
        // parse i for the id
    }
    else if (groupId.HasValue && itemId.HasValue)
    {
        // use groupId and itemId for the id
    }
}

这不是一个完美的解决方案,尤其是当你有很多争论的时候,但它对我来说很有效。

您可以使用[ActionName("NewActionName")]来使用不同名称的相同方法:

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");
    }
}

我已经在MVC5中的属性路由的帮助下实现了这一点。不可否认,我是MVC的新手,因为我使用WebForms进行了十年的web开发,但下面的方法对我来说是有效的。与已接受的答案不同,这允许所有重载操作由相同的视图文件呈现。

首先启用“App_Start/RouteConfig.cs”中的“属性路由”。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );            
    }
}

可选地用默认路由前缀装饰控制器类。

[RoutePrefix("Returns")]
public class ReturnsController : BaseController
{
    //.......

然后装饰你的控制器动作,让它们用公共的路由和参数相互重载。使用类型约束参数,您可以使用具有不同类型id的相同URI格式。

[HttpGet]
// Returns
public ActionResult Index()
{
    //.....
}

[HttpGet]
[Route("View")]
// Returns/View
public ActionResult View()
{
    // I wouldn't really do this but it proves the concept.
    int id = 7026;
    return View(id);
}

[HttpGet]
[Route("View/{id:int}")]
// Returns/View/7003
public ActionResult View(int id)
{
    //.....
}

[HttpGet]
[Route("View/{id:Guid}")]
// Returns/View/99300046-0ba4-47db-81bf-ba6e3ac3cf01
public ActionResult View(Guid id)
{
    //.....
}

希望这对你有所帮助,不要把别人引向错误的道路。: -)

如果您希望代码进行重载,可以使用该属性。

[ActionName("MyOverloadedName")]

但是,您必须为相同的http方法使用不同的操作名称(正如其他人所说)。所以这只是语义上的。您希望在代码中使用名称还是属性中使用名称?

Phil有一篇相关的文章:http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx

This answer for those who struggling with the same issue. You can implement your own custom filter based on ActionMethodSelectorAttribute. Here I found the best solution for solving your question. Works fine on .net 5 project. If you try to implement the same logic as was in web api controllers then use Microsoft.AspNetCore.Mvc.WebApiCompatShim. This nuget package provides compatibility in ASP.NET Core MVC with ASP.NET Web API 2 to simplify migration of existing Web API implementations. Please check this answer but consider that starting with ASP.NET Core 3.0, the Microsoft.AspNetCore.Mvc.WebApiCompatShim package is no longer available.