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

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


当前回答

将基方法创建为virtual

public virtual ActionResult Index()

将被覆盖的方法创建为override

public override ActionResult Index()

编辑:这显然只适用于当override方法在一个派生类中,而这似乎不是OP的意图。

其他回答

我需要一个过载:

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

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

是的。我已经能够通过为每个控制器方法设置HttpGet/HttpPost(或等效的AcceptVerbs属性)来做到这一点,即HttpGet或HttpPost,但不是两者都有。这样它就可以根据请求的类型来判断使用哪个方法。

[HttpGet]
public ActionResult Show()
{
   ...
}

[HttpPost]
public ActionResult Show( string userName )
{
   ...
}

我的一个建议是,对于这种情况,应该有一个私有实现,你的两个公共Action方法都依赖于它,以避免重复代码。

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

好运!

我喜欢这个贴在另一个帖子里的答案

这主要用于从另一个控制器继承,并希望重写来自基本控制器的操作

ASP。用不同的参数覆盖一个动作

据我所知,你只能有相同的方法时,使用不同的http方法。

i.e.

[AcceptVerbs("GET")]
public ActionResult MyAction()
{

}

[AcceptVerbs("POST")]
public ActionResult MyAction(FormResult fm)
{

}