简体   繁体   中英

ASP.NET MVC3 view authorization design

Imagine you have a secured site and a View that can be generated in multiple ways, depending on the user role. Say, an Admin sees all, Manager sees some columns and some action buttons, User sees other columns and other action buttons.

How would you implement this? As far as I see it, there are three main options:

  • Controller with [Authorize] attribute and the action returning 1 View per user role, being those views tailored to the role;
  • Controller with [Authorize] attribute and the action returning 1 View for all roles, with logic to hide/show columns, fields, buttons;
  • Controller with [Authorize] attribute and the action returning 1 View, which based on the roles renders different Partial Views.

I prefer the third approach, but do you see a better way to implement this?

Thank you in advance

Depending on the complexity of your view, either the first or the third option would seem ok to me. As for the second option; Its generally recommended to avoid logic in views so I'd stay away from that one.

If you go for the third option you should consider using EditorTemplates and DisplayTemplates. This will allow you to make your (main) view agnostic to what partial view to render. Make your viewmodel (or part of it) inherit from a single base class. Create display and/or editor templates for each view model type and in your view just say Html.DisplayFor( ... ) or Html.EditorFor( ... ) . MVC will automatically pick the right template, without the need for logic in your view.

What I have been doing for menus and other navigational items is that I have a ViewModel class for it. Here is a simplified version.

ViewModel

public class Action
{
    public string DisplayName { get; set; } // localized
    public string Url { get; set;
}

public class MenuViewModel
{
    public List<Action> Actions { get; set; }

    public MenuViewModel()
    {
        this.Actions = new List<Action>();
    }
}

I fill that depending on the user role. Admin gets more links etc.

That ViewModel is part of "main" view model

public class AlbumEditorViewModel
{
    public MenuViewModel Menu { get; set; }
}

Then I'll pass that view model for the partial view that is responsible for the menu.

View (Razor)

@model AlbumEditorViewModel

.. razor stuff here ..
@Html.Partial("Menu", Model.Navigation)
.. razor stuff here ..

Partial View

@model MenuViewModel

<ul>
    @foreach (var action in Model.Actions)
    {
        <li>
            @GridHelper.GetAction(action)
        </li>
    }
</ul>

I hope that this will give you ideas

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM