路由到同名但参数不同的动作

Posted

技术标签:

【中文标题】路由到同名但参数不同的动作【英文标题】:Routing to the actions with same names but different parameters 【发布时间】:2011-02-07 05:52:01 【问题描述】:

我有这组路线:

        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

【问题讨论】:

【参考方案1】:

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

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

编辑:

如何创建一个自定义属性来查找特定请求值,如本文*** 中所述

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

【讨论】:

是的,这很明显,但实际上并不是解决问题的方法 是的,这会带来某种重载但太脏,所以我选择简单地重命名第二种方法。谢谢【参考方案2】:

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

public ViewResult Index()

    //...

// AND
public ViewResult Index(int entryId)

    //...

我只是将它们合并并更改为:

public ViewResult Index(int entryId = 0)

    //...

【讨论】:

这可能是 .NET 4.0 的解决方案,但我当时使用的是 3.5 ;-)【参考方案3】:

您可以使用使用反射检查参数的 ActionFilterAttribute 来做到这一点(我试过了),但这是个坏主意。 每个不同的动作都应该有自己的名字。

为什么不直接称你的两个方法为“Index”和“Single”,并忍受命名的限制?

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

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

【讨论】:

我已经重命名了第二个,所以我有两种方法。实际上,我得到了很多指向 ActionFilterAttribute 的链接 - 这是一个更糟糕的解决方案。还是谢谢你。【参考方案4】:

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

public class IssueController : Controller

    public ActionResult Index()
    
        // todo: redirect to concrete type
        return View();
    

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

【讨论】:

谁告诉你第二个已经发布了? 我经常看到这种情况,尤其是对于登录方法 - 一个 Get 操作提供初始视图,而 Post 接受登录请求并重定向。一般来说,我在第一个标签上也看到了[HttpGet] 标签,不确定哪个(如果有)框架版本需要这个标签,但是标记两者更容易推理。

以上是关于路由到同名但参数不同的动作的主要内容,如果未能解决你的问题,请参考以下文章

包体中有两个同名但参数不同的函数是啥意思?

Angular 5:用于导航到相同路线但参数不同的路线动画

React Router v4 - 使用不同的查询参数重定向到相同的路由

重载重写隐藏

如何导入同名但路径不同的组件?

Angular rc3 路由器 - 使用不同参数导航到同一页面