Search code examples
asp.netasp.net-coreroutesasp.net-mvc-routing

How can I achieve a in-url routing in asp.net core?


I am trying to achieve a routing style such as:

mydomain.com/some-slug-text-a-123

The last digits is the Id of the particular resource and the 'a' before that will represent the resource. Resources might be a for Article, p for Product and so on. Obviously for each resource I have a separate controller and my challange starts here.

In this case, apart from using the Home controller and serving all the content depending on the resource provided, is there a routing configuration specific to this scenario?

I am sorry if this has been an opinion based question but don't know how else to ask.


Solution

  • You have multiple ways to achive that. I'll will give you two examples, but I suggest taking a look into Asp.Net Routing documentation

    Option 1 (Multiple Convetional Routes)

    Map new route conventions on Startup.cs (method Configure)

    app.UseEndpoints(endpoints =>
    {
        // Map articles (a)
        endpoints.MapControllerRoute(name: "a",
                    pattern: "{*slug}-a-{*id}",
                    defaults: new { controller = "Blog", action = "Article" });
    
        // Map products (p)
        endpoints.MapControllerRoute(name: "p",
                    pattern: "{*slug}-p-{*id}",
                    defaults: new { controller = "Store", action = "Product" });
    
        // Default routing
        endpoints.MapControllerRoute(name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
    });
    

    Create a controller and action that receive the parameters setted on your route convetion:

        public class BlogController : Controller
        {
            [HttpGet]
            public ActionResult Article(string slug, int id)
            {
                // Your code here
            }
        }
    
    

    Option 2 (Attribute routing)

    Map new route conventions on Startup.cs (method Configure)

    app.UseEndpoints(endpoints =>
    {
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    

    Add the attribute [Route("")] to your controller and/or action. I put the attribute just on action to simplify the example

        public class BlogController : Controller
        {
            [Route("/{slug}-a-{id}")] 
            public ActionResult Article(string slug, int id)
            {
                // Your code here
            }
        }
    
        public class StoreController : Controller
        {
            [Route("/{slug}-p-{id:int}")] // ":int means that the route will only accept an valid integer on this route; otherwiase will return NotFound
            public ActionResult Product(string slug, int id)
            {
                // Your code here
            }
        }