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

asp.net-mvcasp.net-mvc-routingroutingurl-routing

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.

Best Answer

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

Related Topic