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

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


当前回答

为了克服这个问题,你可以编写一个ActionMethodSelectorAttribute来检查每个动作的MethodInfo,并将其与发布的表单值进行比较,然后拒绝任何与表单值不匹配的方法(当然,不包括按钮名称)。

举个例子:- http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

但是,这不是一个好主意。

其他回答

我刚刚遇到了这个问题,尽管它现在已经很古老了,但它仍然非常相关。具有讽刺意味的是,这个帖子中唯一正确的评论是由一个自称MVC初学者的人在写这篇文章时发表的。甚至是ASP。NET文档并不完全正确。我有一个大项目,我成功地重载动作方法。

如果你了解路由,除了简单的{controller}/{action}/{id}默认路由模式,很明显,控制器动作可以使用任何唯一的模式进行映射。有人在这里谈论多态性,说:“HTTP不理解多态性”,但路由与HTTP无关。简单地说,它是字符串模式匹配的机制。

最好的方法是使用路由属性,例如:

[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
    }
}

这些操作将处理类似/cars/usa/new-york和/cars/usa/texas/dallas这样的url,它们将分别映射到第一个和第二个索引操作。

检查这个示例控制器,很明显它超出了上面提到的默认路由模式。如果您的url结构完全匹配您的代码命名约定,则默认值工作良好,但情况并非总是如此。代码应该对域名进行描述,但url通常需要更进一步,因为它们的内容应该基于其他标准,比如SEO要求。

默认路由模式的好处是它自动创建唯一的路由。这是由编译器强制执行的,因为url将匹配唯一的控制器类型和成员。使用自己的路线模式需要仔细考虑,以确保独特性和它们的工作。

重要提示:一个缺点是,使用路由为重载操作生成url在基于操作名称时不起作用,例如,当使用UrlHelper.Action时。但是,如果使用命名路由,例如UrlHelper.RouteUrl,它就可以工作。根据权威人士的说法,使用命名路线是正确的方法(http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.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.

我需要一个过载:

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
    }
}

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

不,不,不。去试试下面的控制器代码,在这里我们重载了“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动作重载

抱歉耽搁了。我也遇到过同样的问题,我找到了一个有很好的答案的链接,可以帮助新人

所有的功劳为BinaryIntellect网站和作者

基本上,有四种情况:使用不同的动词、使用路由、使用[NoAction]属性进行重载标记以及使用[ActionName]更改操作属性名称。

这取决于你的需求和你的情况。

无论如何,请点击以下链接:

链接: http://www.binaryintellect.net/articles/8f9d9a8f-7abf-4df6-be8a-9895882ab562.aspx