Question

I have a default route set up in my ASP.NET MVC2 project and would like to add/modify it for some of my other controllers. Lets say I have a Customer controller with Details action that expects and "id" parameter (int). For example:

    //
    // GET: /Customer/Details/5
    public ActionResult Details(int id)
    {
      //...
    }

How can I add a route that will return a 404 if a user enters a "non-number"? I tried adding following "before" default route but it did not work...

    routes.MapRoute(
        "DefaultDigitsId", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index" },
        new { id = @"\d+" }
        );

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

Note, I would like, if possible, to keep default route... All of my controllers use "Details" and "Edit" where "id" (int) parameter is required.. I am wondering if there is a way to accomplish this without having to specify multiple routes (i.e. something generic)...And of course, the goal is that if user enters something like "/Customer/Details/apple" it does not throw an error but takes them to Error page...

There is also this post that hints to setting a default value but I am not sure how to do it...

Was it helpful?

Solution

I haven't tried this, but you might want to give it a try:

routes.MapRoute(
    "DefaultDetails",
    "{controller}/Details/{id}",
    new { controller = "Home", action = "Details" },
    new { id = @"\d+" }
    );

routes.MapRoute(
    "DefaultEdit",
    "{controller}/Edit/{id}",
    new { controller = "Home", action = "Edit" },
    new { id = @"\d+" }
    );

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );

I would expect that "Customer/Details/1" uses the first route (which validates the id as a number, a call to "Customer/Edit/1" uses the second, which does likewise, and a call to "Customer/Buy/Orange" uses the third route, which doesn't try to validate IDs in this way. Did I understand what you're trying to do correctly? Let me know if this approach works.

OTHER TIPS

Add an IgnoreRoute after the one that matches a numeric id that will ignore any requests to the Details action on the Customer controller:

routes.MapRoute(
  "DefaultDigitsId", // Route name
  "{controller}/{action}/{id}", // URL with parameters
  new { controller = "Home", action = "Index" },
  new { id = @"\d+" } // match numeric id
);

routes.IgnoreRoute("Customer/Details/{*pathInfo}");

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

Any value that cannot be parsed to a string will make the id value be null on call, so you could redirect to the error page if the id is not null.

Another possibility is registering a global filter that checks if there's a parameter named id and if it is null, then redirects to the error page

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top