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

孤人 提交于 2020-01-12 12:49:26

问题


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.


回答1:


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




回答2:


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



回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/5591569/asp-net-mvc-routing-how-to-use-default-action-but-non-default-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!