asp.netasp.net-mvcurl

ASP.NET MVC url construction


Before I ask my question: I just started ASP.NET MVC, so an advanced answer will maybe hard to understand ;)

I'm having 3 tables (I'll add just a few of the fields below)

Now what I want to do is this:

www.site.com/Shops

//Gives me a list of shops

www.site.com/Shops/ShopName

//Gives me some details about the shop called ShopName and lists all the products that the shop has

www.site.com/Shops/ShopName/ProductName/

//Gives me all the comments of that product called ProductName from that specific shop called ShopName

www.site.com/Shops/ShopName/ProductName/ASpecificCommentHere

//Gives me a specific comment on that product of that shop

and other things like

www.site.com/Shops/ShopName/ProductName/AddComment

//Adds a new comment to that product from that shop

Now I only have a ShopsController which makes it possible for me to do something like this now:

www.site.com/Shops/

// Gives me a list of all shops

and

www.site.com/Shops/Details/123

// Gives me some details about the shop with ID 123 and should list its products.

But here is also the first problem: I don't want the ID number in the url like /Shops/123 but rather the name like /Shops/ShopName and I don't know if it's good to have /Details/ there in the url. Maybe /Shops/ShopName would be better without the Details part in between?

How should I do this? Should I create also a Controller for my Products and for my Comments that I have 3 controllers in total? Or should I just keep one ShopController to always get the first part of the url (so that it always starts with) site.com/Shops/ShopName/...

Thanks in advance

(and a short little question, should ViewModels be placed in the controllers directory?)


Solution

  • Kind a doing your work, but - whatever.
    I would go with something like this (be warned - it's untested)...

    As you already likely know - order is important.

    www.site.com/Shops/ShopName/ProductName/AddComment =>

    routes.MapRoute(
        "Product",
        "Shops/{shopName}/{productName}/{action}",
        new { controller="comment"}
    );
    

    www.site.com/Shops/ShopName/ProductName/ASpecificCommentHere =>

    routes.MapRoute(
        "Product",
        "Shops/{shopName}/{productName}/{commentName}",
        new { controller="comment", action="details"}
    );
    

    www.site.com/Shops/ShopName/ProductName/AddProduct =>

    routes.MapRoute(
        "Product",
        "Shops/{shopName}/{productName}/{action}",
        new { controller="product"}
    );
    

    www.site.com/Shops/ShopName/ProductName/ =>

    routes.MapRoute(
        "Product",
        "Shops/{shopName}/{productName}",
        new { controller="product", action = "details"}
    );
    

    www.site.com/Shops/ShopName =>

    routes.MapRoute(
        "ShopDetails",
        "Shops/{shopName}",
        new { controller="shop", action = "details"}
    );
    

    www.site.com/Shops (NB: this route is 'global', for every controller) =>

    routes.MapRoute(
        "List",
        "{controller}",
        new { action = "list"}
    );
    

    Maybe this can be optimized or worse - it's wrong but it should give you some better understanding for sure.

    Remember not to name shops/controllers/comments as according controller actions. That's an issue with this routing approach.

    And i hope you noticed that i would create 3 different controllers (what might and might not be a good decision - that's based on expectable weight and complexity of controller logic).

    Another tip - read about model binding. Using custom binders you could replace string parameters (entity names) with actual, already assembled objects. Maybe that wouldn't be worth for this particular case, but model binding surely is 2nd important and hardest thing to grasp when facing asp.net mvc.

    And i lied, i wouldn't go with this because i prefer specifying controller specific routes using attributes directly on actions (omitted that because it seems more advanced).

    Routing is like regular expressions. There's a moment when it just 'clicks' and seems natural and easy.


    Already answered second question as comment to your question. :)