tags:

views:

85

answers:

2

Say I have an asp.net mvc website with a page that lists products. ON that page I have a "delete" button that should only show up for the user that inserted the product. What's the best way to do this?

One way I thought of doing it was setting a boolean in the controller to let the view know if the button should be displayed. Something like:

if(IsProductOwner(UserId))
    ViewData["CanDelete"] = true;

Then in the view I can just do

<% if((boolean)ViewData["CanDelete"] == true) { %>
    // show delete button
<% } %>

But is there a better way to do this?

+2  A: 

My initial thought is that you should at least make that a function of the Product class so you can go:

<% if (product.IsOwnedBy(UserId)) { %>
    // show delete button
<% } %>

This removes some of the floaty ViewData and builds the business logic into your classes rather than floating out on the edges.

However, I haven't found a decent way to do this sort of conditional display in views unless the view is significantly different then I get the action to display a different view depending on the context.

Garry Shutler
On one hand I really like your approach as it's very clean. However, since it's a list of products on the page that means every product will require a database hit. 50 products = 50 database roundtrips. Interestingly enough, all the products listed on a page will be from the same user. So this makes me lean towards the original solution of adding a ViewData["CanDelete"] (which I still don't like) :)
codette
Well I'm imagining your product holds against it which user owns it so you would already have that information and no round-trip would be required. Depends on how your system is structured I suppose.
Garry Shutler
Actually you are right! Ok this is the solution I will go with. Thanks!
codette
Spoke too soon. ssg brings up a good point and solution
codette
ok, after spending much of my day refactoring my code it looks like this is the best way to go. ssg's solution works great if all the products are by the same user. but once you mix up products from different users this solution works best
codette
+1  A: 

MVC is about separating business logic from presentation. The answer provided by Garry looks dirty (and non-performant) from that aspect. You can instead use strongly typed ViewData and more common data points to achieve the same. e.g. Instead of ViewData["CanDelete"] you can use ViewData.IsOwned and use that variable around on more than one occasion, avoiding variable inflation. So your business code becomes:

ViewData.IsOwnedByThisUser = product.IsOwnedBy(currentUserId);

And your view code becomes:

<% if(ViewData.IsOwnedByThisUser) { %>
// show delete button
<% } %>

You can use same variable for "edit" buttons as well.

The difference in this approach is you completely detach view presentation from your business logic. Your business logic can change (and your controller can adapt to it) but you don't ever need to change your view code, unless your application design goes under a significant change.

ssg
Looks like yours and Garry's solution are just about the same. The model should be the one to determine who it is owned by.
Peter J
product is a model class. in my approach model class can change "completely" without affecting view implementation.
ssg