简体   繁体   中英

MVC4 Route as /{controler}-{id} instead of /{controler}/{id}

During my work I must solve one URL rewriting problem. I have to use URLs as a template:

{controller}/{action}-{id}

instead of

{controller}/{action}/{id}

so the processed url should look like:

myController/myAction-128

where 128 is a parameter

My route map:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

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

Controller code:

[HttpGet]
        public ActionResult DocumentDetails(int? id)
        {
            if (doc.HasValue)
            {
              ...
            }
        }

This route doesn't provide any successful results. I still have 404 Errors. When I use / instead of "-" everything is ok, but my JS View environment won't work.

Is there something I could do to fix this? All help will be appreciated, thanks.

Routes are evaluated in the same order as you defined them, so make sure you respect the same order. Also adding a constraint for the id (as being a number for example) would help the routing engine disambiguate your routes. Not to mention that in your example you have made the id token optional which of course is not possible, only the last part of a route can be optional.

So:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "NewRoute",
        url: "{controller}/{action}-{id}/{extId}",
        defaults: new { controller = "Home", action = "Index", extId = UrlParameter.Optional },
        new { id = @"\d+" }
    );

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

I'm thinking your request is being processes by the first routing rule and then action-id is considered as a whole action and not being found.

Set your NewRoute before the Default route. Just move the code up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM