简体   繁体   中英

Custom ASP.NET Core route with id and title separated by hyphen

In ASP.NET Core, I want to generate some kind of SEO-URLs, that contains the id of an entry and also his title.

Example: example.com/News/ViewNews/123-test-news

In Startup.cs I defined the following Route

            routes.MapRoute(
                name: "SeoNews",
                template: "{controller=News}/{action=ViewNews}/{id:int}-{title}"
            );

In the News-Controller, the following Action exists

        public IActionResult ViewNews(int id, string title) { }

The breakpoint inside gave me empty values, so id = 0 and title = null.

Calling

Example: example.com/News/ViewNews/123

Gave me id = 123, but empty title cause it's not present in the URL. Whats wrong with my Rewrite-Route?

Other Routes I've defined after my custom route:

            routes.MapRoute(
                name: "AreaRoute",
                template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
            );

            routes.MapRoute(
                name: "DefaultMVCRoute",
                template: "{controller=Dashboard}/{action=Index}/{id?}"
            );

EDIT I tried replacing the hyphen with a slash like SO do, so the routing template is {controller=News}/{action=ViewNews}/{id:int}/{title} . That works perfectly.. Can't understand why. I already tried to escape the hyphen, cause it may conflicts as special char from regular expressions, which doesn't work too.

Using a slash as delimitter is a suiteable workaround for me. But I'm interested to know what's special on this char, that it doesn't work, so I renamed the question title.

I guess you mean slug instead of title? Title would imply that you want to use it as parameter. A slug is only there for the sake of having a more describable URL, but isn't actually used in the real routing.

This case is very well documented in the ASP.NET Core documentation already in the " Routing in ASP.NET Core " article.

You can use the * character as a prefix to a route parameter to bind to the rest of the URI - this is called a catch-all parameter. For example, blog/{*slug} would match any URI that started with /blog and had any value following it (which would be assigned to the slug route value). Catch-all parameters can also match the empty string.

routes.MapRoute(
        name: "SeoNews",
            template: "{controller=News}/{action=ViewNews}/{id:int}/{*slug}"
        );

One reason why {controller=News}/{action=ViewNews}/{id:int}-{title} doesn't work is that title is not optional. Second is it tries to match the whole pattern between the slashes, so you can just have one parameter per segment.

You could also try this, but I doubt it will work

routes.MapRoute(
        name: "SeoNews",
            template: "{controller=News}/{action=ViewNews}/{id:int}{*slug}"
        );

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