2010-04-12 32 views
20

我有这个路由集合:路由到有相同的名字,但不同参数的操作

 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

回答

10

我将具有寻找一个有效的类型变量一个索引方法

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; } 
} 
+0

是的,很明显,但对这一问题 – zerkms 2010-04-13 03:14:59

+1

是的没有实际的解决方案,这带来了一些有些超载但太脏,所以我选择重新命名第二种方法。谢谢 – zerkms 2010-04-13 05:17:23

1

你可以使用一个ActionFilterAttribute来检查参数(我试过),但这是一个坏主意。 每个不同的操作应该有自己的名字。

为什么不直接调用你的两个方法“索引”和“单个”,并说出命名的限制?

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

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

+0

我已经重命名第二,所以我有2种方法。而且我得到了很多ActionFilterAttribute的链接,的确 - 这是一个糟糕的解决方案。不管怎样,谢谢你。 – zerkms 2010-04-13 05:16:18

1

您只需用[HttpPost]标记您的第二个动作即可。例如:

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

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

谁告诉你第二个邮寄地址? – zerkms 2011-08-27 23:31:57

+0

对我来说似乎很奇怪... – 2015-03-16 16:09:35

+0

我经常看到这种情况,特别是对于登录方法 - 一个获取操作以提供初始视图,另一个获取操作以接受登录请求并重定向。通常我也看到了第一个''[HttpGet]'标签,不确定哪个(如果有的话)框架版本需要这个标签,但是标记这两个标签使得它更容易推理。 – brichins 2018-01-12 17:57:55

5

我遇到类似的情况,我想我的“指数”的行动来处理渲染,如果我有一个ID指定与否。我遇到的解决方案是将Index参数的ID参数设置为可选。 例如,我最初试图同时具有:

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

,我只是将它们结合在一起,并把它改为:

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

这可能是.NET 4.0的解决方案,但我使用的是3.5那些日子;-) – zerkms 2011-09-02 22:29:12

相关问题