asp.net-mvc 路由到具有相同名称但不同参数的操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2626179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:15:50  来源:igfitidea点击:

Routing to the actions with same names but different parameters

asp.net-mvcrouting

提问by zerkms

I have this set of routes:

我有这组路线:

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

Here is the controller class:

这是控制器类:

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

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

why, when i request http://host/issuei get The current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:
I expect that first one method should act when there is no parameters, and second one when some parameter specified.

为什么,当我要求的http://主机/问题我得到The current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:
我期望的时候没有参数,并指定一些参数时,第二个第一个方法应该采取行动。

where did i made mistake?

我哪里弄错了?

UPD: possible duplicate: Can you overload controller methods in ASP.NET MVC?

UPD:可能重复:您可以在 ASP.NET MVC 中重载控制器方法吗?

UPD 2: due to the link above - there is no any legal way to make action overloading, is it?

UPD 2:由于上面的链接 - 没有任何合法的方法可以使动作超载,是吗?

UPD 3: Action methods cannot be overloaded based on parameters (c) http://msdn.microsoft.com/en-us/library/system.web.mvc.controller%28VS.100%29.aspx

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

采纳答案by Tommy

I would have one Index method that looks for a valid type variable

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

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

EDIT:

编辑:

How about creating a custom attribute that looks for a specific request value as in this post StackOverflow

如何创建一个自定义属性来查找特定请求值,如这篇文章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; } 
} 

回答by jgreg311

I ran into a similar situation where I wanted my "Index" action to handle the rendering if I had an ID specified or not. The solution I came upon was to make the ID parameter to the Index method optional. For example, I originally tried having both:

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

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

and I just combined them and changed it to:

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

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

回答by Ian Mercer

You can do it using an ActionFilterAttribute that checks the parameters using reflection (I tried it) but it's a bad idea. Each distinct action should have its own name.

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

Why not just call your two methods "Index" and "Single", say, and live with the limitation on naming?

为什么不把你的两个方法称为“索引”和“单一”,比如说,忍受命名的限制?

Unlike methods that are bound at compile time based on matching signatures, a missing route value at the end is treated like a null.

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

If you want the [hack] ActionFilterAttribute that matches parameters let me know and I'll post a link to it, but like I said, it's a bad idea.

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

回答by 010110110101

All you have to do is mark your second Action with [HttpPost]. For instance:

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

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

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