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

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


当前回答

你可以使用一个ActionResult来处理Post和Get:

public ActionResult Example() {
   if (Request.HttpMethod.ToUpperInvariant() == "GET") {
    // GET
   }
   else if (Request.HttpMethod.ToUpperInvariant() == "POST") {
     // Post  
   }
}

如果您的Get和Post方法具有匹配的签名,则非常有用。

其他回答

您可以使用[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");
    }
}

我刚刚遇到了这个问题,尽管它现在已经很古老了,但它仍然非常相关。具有讽刺意味的是,这个帖子中唯一正确的评论是由一个自称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/)。

好运!

我需要一个过载:

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

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

我在申请的时候也遇到过同样的问题。没有Modifiyig任何方法信息,我已经提供了[ActionName(“SomeMeaningfulName”)]在动作头部。问题解决

[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);

        }

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

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

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