views:

122

answers:

2

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)

  • Shops (ShopID, Name)
  • Products (ProductID, Name, ShopID)
  • Comments (CommentID, ProductID, UserID, CommentText)

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?)

A: 

I would spend a little time researching the routing mechanism in MVC. This is where you set the formats for the URLs your application should receive. All the things you mentioned are possible...you just need to construct your route definitions accordingly. As far as being able to accept the name of the entity, rather than the ID, you can do that very easily by constructing your route so that it accepts names and changing the signatures on your action methods to accept strings instead of ints.

I don't know what the official stance on where ViewModels should be located. It's really up to you, and it depends on the ORM method you are implementing. I'm using LINQ-to-SQL, and having a very good time with it. I keep my LINQ-to-SQL model in my Models folder. I prefer to keep my ViewModels in a View subfolder under my Models folder. I've also got a Domain subfolder to hold the partial models for my entities, in case I want to implement calculated fields or set up the initial values for the record.

Neil T.
+1  A: 

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. :)

Arnis L.
oh... glad to see it actually helped! :)
Arnis L.