路由到具有相同名称但不同参数的操作

时间:2010-04-12 23:55:15

标签: asp.net-mvc routing

我有这套路线:

        routes.MapRoute(
            "IssueType",
            "issue/{type}",
            new { controller = "Issue", action = "Index" }
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

这是控制器类:

public class IssueController : Controller
{
    public ActionResult Index()
    {
        // todo: redirect to concrete type
        return View();
    }

    public ActionResult Index(string type)
    {
        return View();
    }
}

为什么,当我请求http://host/issue时,我得到The current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:
我希望第一个方法应该在没有参数时起作用,第二个方法应该在指定某个参数时起作用。

我哪里弄错了?

UPD :可能重复:Can you overload controller methods in ASP.NET MVC?

UPD 2 :由于上面的链接 - 没有任何合法的方法来执行操作重载,是吗?

UPD 3 :根据参数(c)http://msdn.microsoft.com/en-us/library/system.web.mvc.controller%28VS.100%29.aspx无法重载操作方法

4 个答案:

答案 0 :(得分:11)

我会有一个Index方法来查找有效的类型变量

    public class IssueController : Controller  
{  
    public ActionResult Index(string type)  
    {  
        if(string.isNullOrEmpty(type)){
            return View("viewWithOutType");}
        else{
            return View("viewWithType");} 
    }
}

编辑:

如何在帖子StackOverflow

中创建查找特定请求值的自定义属性
[RequireRequestValue("someInt")] 
public ActionResult MyMethod(int someInt) { /* ... */ } 

[RequireRequestValue("someString")] 
public ActionResult MyMethod(string someString) { /* ... */ } 

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute { 
    public RequireRequestValueAttribute(string valueName) { 
        ValueName = valueName; 
    } 
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { 
        return (controllerContext.HttpContext.Request[ValueName] != null); 
    } 
    public string ValueName { get; private set; } 
} 

答案 1 :(得分:5)

我遇到了类似的情况,如果我指定了ID,我希望我的“索引”操作能够处理渲染。我遇到的解决方案是使Index方法的ID参数可选。 例如,我最初尝试过两者:

public ViewResult Index()
{
    //...
}
// AND
public ViewResult Index(int entryId)
{
    //...
}

我只是将它们组合起来并改为:

public ViewResult Index(int entryId = 0)
{
    //...
}

答案 2 :(得分:1)

您可以使用ActionFilterAttribute来执行此操作,该ActionFilterAttribute使用反射检查参数(我尝试过),但这是一个坏主意。 每个不同的操作都应该有自己的名称。

为什么不直接将你的两种方法称为“索引”和“单一”,并且遵守命名限制?

与基于匹配签名在编译时绑定的方法不同,最后将缺少的路由值视为null。

如果你想要匹配参数的[hack] ActionFilterAttribute让我知道,我会发布一个链接,但就像我说的那样,这是一个坏主意。

答案 3 :(得分:1)

您所要做的就是用[HttpPost]标记您的第二个动作。例如:

public class IssueController : Controller
{
    public ActionResult Index()
    {
        // todo: redirect to concrete type
        return View();
    }

    [HttpPost]
    public ActionResult Index(string type)
    {
        return View();
    }
}