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

发布于 2024-10-31 10:04:29 字数 2419 浏览 1 评论 0原文

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

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

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

在此示例中,如果未指定控制器,则将使用 DefaultPageController,如果未指定操作,则将使用“Index”操作。 网址通常如下所示:http://mysite/MyController/MyAction

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

现在假设我的控制器中有两个操作 Index 和 AnotherAction。与它们对应的url分别是http://mysite/MyControllerhttp://mysite/MyController/AnotherAction。我的“索引”操作接受一个参数 id。因此,如果我需要将参数传递给 Index 操作,我可以这样做: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 不是一个操作(因为我有没有定义具有此名称的操作),而是我的默认操作“Index”的参数。如何设置路由来实现此目的?

以下是问题的原文。


我有一个控制器,它定义了两种方法,如下所示

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

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

    }

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

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

http://website/Page/123

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

我该如何设置路由才能正常工作?目前,我有由向导生成的“默认”路由,如下所示:

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

我尝试添加另一个控制器方法,如下所示:

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

但这不起作用,因为抛出了不明确的操作异常:

当前请求的操作“索引” 在控制器类型“PageController”上 以下各项之间有歧义 行动方法: System.Web.Mvc.ActionResult 索引() 上 类型页面控制器 System.Web.Mvc.ActionResult PageController 类型上的索引(Int32)

,我在此控制器中还有其他操作。 如果我不这样做,这就会起作用。

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:

        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.

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

Now let's assume I have two actions in my controller Index and AnotherAction. The urls that correspond to them are http://mysite/MyController and http://mysite/MyController/AnotherAction respectively. 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/123 instead 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?

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/Page both when the user navigates to this url (GET) and when they subsequently post back the form (POST).

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

http://website/Page/123

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

奢欲 2024-11-07 10:04:29

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

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

考虑以下代码:

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

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

来源:创建路由约束

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.

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/123 so it will not interfere with calling another action on the same controller.

Source: Creating a Route Constraint

三生殊途 2024-11-07 10:04:29

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

将帖子重命名为“PostIndex”并添加此属性:

[ActionName("Index")]

SO 这里

好的,如果有帮助的话,这是给您的剪切/粘贴答案。

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

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

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

[ActionName("Index")]

Same question on 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();    
}
伊面 2024-11-07 10:04:29

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

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

附:默认路由如 /MyController/id 最后必须映射。

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/id must mapped at last.

清晨说晚安 2024-11-07 10:04:29

我认为你想要返回相同的观点,但你需要明白你正在做两件不同的事情。一种是接收post,另一种是通过get访问,还有一种是通过get和参数访问...

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

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...

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文