asp.net-mvc asp.net mvc 路由:如何使用默认操作但非默认参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5591569/
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 01:06:09  来源:igfitidea点击:

asp.net mvc routing: how to use default action but non-default parameter?

asp.net-mvcroutingurl-routingasp.net-mvc-routing

提问by Andrew Savinykh

I'm rewriting the question, as the answers so far show me that I have not defined it good enough. I'll leave the original question for reference below.

我正在重写这个问题,因为到目前为止的答案告诉我,我对它的定义还不够好。我将在下面留下原始问题以供参考。

When you set up your routing you can specify defaults for different url/route parts. Let's consider example that VS wizard generates:

设置路由时,您可以为不同的 url/路由部分指定默认值。让我们考虑 VS 向导生成的示例:

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

In this example if controller is not specified, DefaultPageController will be used and if action is not specified "Index" action will be used. The urls will generally look like: http://mysite/MyController/MyAction.

在此示例中,如果未指定控制器,则将使用 DefaultPageController,如果未指定操作,则将使用“索引”操作。该网址通常是这样的:http://mysite/MyController/MyAction

If there is no action in Url like this: http://mysite/MyControllerthen the index action will be used.

如果 Url 中没有像这样的操作:http://mysite/MyController那么将使用索引操作。

Now let's assume I have two actions in my controller Index and AnotherAction. The urls that correspond to them are http://mysite/MyControllerand http://mysite/MyController/AnotherActionrespectively. My "Index" action accepts a parameter, id. So If I need to pass a parameter to my Index action, I can do this: http://mysite/MyController/Index/123. Note, that unlike in URL http://mysite/MyController, I have to specify the Index action explicitly. What I want to do is to be able to pass http://mysite/MyController/123instead of http://mysite/MyController/Index/123. I do not need "Index" in this URL I want the mvc engine to recognize, that when I ask for http://mysite/MyController/123, that 123 is not an action (because I have not defined an action with this name), but a parameter to my default action "Index". How do I set up routing to achieve this?

现在让我们假设我的控制器 Index 和 AnotherAction 中有两个动作。与它们对应的网址分别是http://mysite/MyControllerhttp://mysite/MyController/AnotherAction。我的“索引”操作接受一个参数 id。所以,如果我需要一个参数传递给我的指标作用,我可以这样做:http://mysite/MyController/Index/123。请注意,与 URL 不同http://mysite/MyController,我必须明确指定 Index 操作。我想做的是能够通过http://mysite/MyController/123而不是http://mysite/MyController/Index/123. 我不需要这个 URL 中的“索引”我希望 mvc 引擎能够识别,当我请求时http://mysite/MyController/123,123 不是一个动作(因为我没有用这个名字定义一个动作),而是我默认动作的一个参数“指数”。如何设置路由来实现这一点?

Below is the original wording of the question.

以下是问题的原始措辞。



I have a controller with two methods definded like this

我有一个控制器,它有两个这样定义的方法

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

    [HttpPost]
    public ActionResult Index(SomeFormData data)
    {
        return View();

    }

This allows me to process Url like http://website/Pageboth when the user navigates to this url (GET) and when they subsequently post back the form (POST).

这允许我http://website/Page在用户导航到此 url (GET) 以及随后回发表单 (POST) 时处理 Url 。

Now, when I process the post back, in some cases I want to redirect the browser to this url:

现在,当我处理回帖时,在某些情况下我想将浏览器重定向到这个 url:

http://website/Page/123

Where 123 is some integer, and I need a method to process this url in my controller.

其中 123 是一些整数,我需要一种方法来在我的控制器中处理这个 url。

How do I set up the routing, so this works? Currently I have "default" routing generated by the wizard like this:

我如何设置路由,所以这有效?目前我有由向导生成的“默认”路由,如下所示:

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

I tried adding another controller method like this:

我尝试添加另一个这样的控制器方法:

public ActionResult Index(int id)
{
    return View();
}

But this doesn't work as ambiguous action exception is thrown:

但这不起作用,因为抛出了模棱两可的动作异常:

The current request for action 'Index' on controller type 'PageController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Index() on type PageController System.Web.Mvc.ActionResult Index(Int32) on type PageController

当前对控制器类型“PageController”上的操作“Index”的请求在以下操作方法之间是不明确的: System.Web.Mvc.ActionResult Index() on type PageController System.Web.Mvc.ActionResult Index(Int32) on type PageController

I must add, that I also have other actions in this controller. Thiswould have worked if I didn't.

我必须补充一点,我在这个控制器中还有其他动作。如果我不这样做,会奏效。

采纳答案by Andrew Savinykh

Here is how this can be resolved:

以下是解决此问题的方法:

You can create a route constraint, to indicate to the routing engine, that if you have something in url that looks like a number (123) then this is an action parameter for the default action and if you have something that does not look like a number (AnotherAction) then it's an action.

您可以创建一个路由约束,以向路由引擎指示,如果 url 中有一些看起来像数字 (123) 的内容,那么这是默认操作的操作参数,如果您有一些看起来不像number (AnotherAction) 那么它就是一个动作。

Consider This code:

考虑这个代码:

routes.MapRoute(
  "MyController", "MyController/{productId}", 
  new {controller="My", action="Index"}, 
  new {productId = @"\d+" });

This route definition will only match numeric values after MyController in http://mysite/MyController/123so it will not interfere with calling another action on the same controller.

此路由定义将仅匹配 MyController in 之后的数值,http://mysite/MyController/123因此它不会干扰在同一控制器上调用另一个操作。

Source: Creating a Route Constraint

来源: 创建路由约束

回答by NKCSS

If you keep the variable name to remain being ID, you don't need to change anything.

如果您将变量名称保留为 ID,则无需更改任何内容。

Rename the post one to "PostIndex" and add this attribute:

将第一篇文章重命名为“PostIndex”并添加此属性:

[ActionName("Index")]

Same question on SO here.

关于 SO here 的相同问题。

Ok, here's a cut/paste answer for you, if that helps.

好的,如果有帮助,这里有一个剪切/粘贴答案。

public ActionResult Index()    {        
return View();    
}    
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]   
public ActionResult PostIndex(SomeFormData data)    {        
return View();    
}

回答by cem

Oh i got it now. I think It's not possible with default route, You need to map custom routes.

哦,我现在明白了。我认为默认路由是不可能的,您需要映射自定义路由。

    // /MyController/AnotherAction
    routes.MapRoute(
        null,
        "MyController/AnotherAction",
        new { controller = "DefaultPage", action = "AnotherAction" }
    );

    // /MyController
    // /MyController/id
    routes.MapRoute(
        null,
        "MyController/{id}",
        new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
    );

ps. Default routes like /MyController/idmust mapped at last.

附:像 /MyController/id 这样的默认路由必须最后映射。

回答by Alberto León

I think you want return the same view, but you need understand you are doing two differents things. One is receive post, and another is accessing by get, and another is accessing by get and parameter...

我认为您想要返回相同的视图,但您需要了解您正在做两件不同的事情。一个是接收post,另一个是通过get访问,另一个是通过get和参数访问......

You should do 3 actionresult with different names, and return de same view as View("ThisIsTheResult")

您应该使用不同的名称执行 3 个 actionresult,并返回与 View("ThisIsTheResult") 相同的视图