views:

53

answers:

3

I have a view to display a list of items. The user can edit, delete or create new items, but according to their authorizations they may or may not be allowed to do some of this actions.

I have the requirement to display only the actions which the current user is allowed to do, but I don't want to clutter the views with authorization if-else's

Despise of being a very common requirement, I can't find a real satisfactory way of doing it.

My best approach so far is to provide an overload to the Html.ActionLink extension method that takes the permission to ask for, but there are going to be more complex scenarios, like hiding entire blocks of html or switching a textbox for a label+hidden.

Is there a better way to do this?

A: 

We had this same issue. We ended up writing a lot of helper methods and in cases where lots of html output was required, we put them in partial views.

Raj Kaimal
+1  A: 

One example I can think of would be to invoke Html.RenderAction (link: http://msdn.microsoft.com/en-us/library/ee703490.aspx), and then pass the link you wish to use as a route value to the action method (it will appear as a parameter on your action). Because it's a RenderAction, you get to go back through the controller process and thus you can have it render whatever view or data you want depending on the user's state.

Example:

<% Html.RenderAction("Permissions" /* Controller */, "PermissionLink", new { Url = "Admin.aspx" }); %>

And your controller would have something like:

public ActionResult PermissionsLink (string url)
{
     // Do Whatever kind of Authentication you want here, Session is available, etc

     if(authenticated)
        return View("Link");
     else
        return View("Blank");
}
Tejs
This is a better way to do what krisg proposes on his answer, but it's still at component level (krisg was at view level). Maybe I'm not crazy enough to do a "RowAction" component and call it every row to render the actions that the user is able to do, but it's possible that I finally implement a checkbox approach with only one toolbar to act on the items. It took me a while, but I got it. Tnks.
David Lay
A: 

Would it not be simpler to create several views with various controls based on what values the user can change, then return the right view based on the user's access rights?

Views should be for presenting information only, there really shouldn't be any conditional logic contained in them, or at least a bare minimum.

I've always found when i get to the point where i'm finding it hard to grok a situation like yours, the best solution is always to go back to the controller and e-assess what i'm passing to the view in the first place.

By the time the View is called to do its job, all of the important 'decisions' should have already been made.

krisg
I understand what you say, but having a view for every decision to be made is not pragmatic.just in my example above there would be 7 views (one for each combination). Now think of a business app with a lot of access-restricted features to a high level of detail. Sometimes composition is the best approach, but even then, there are decisions left to be made at the component level.
David Lay