Search code examples
asp.net-mvcviewadminroles

How can I control what an user/admin can see without logic in views? MVC5


I want to make a short brief of what my app looks like. If you are not logged in, you are seeing the main page, links such as Products/Users/Discounts but when you try to access those links, you are forced to log in.

After you log in as user, you can see the all the links again, but you can access only Products and the Discounts. If you log in as admin, you can access anything. What should I use to hide those links depending of your role? (unregistered/user/admin)

I dont want to use logics in the Views.

For restricting the access I'm using an Attribute and I pass to Session the current UserViewModel which has a role property.

Thanks!


Solution

  • You can make your menu dinamically, passing values according to the user's profile.

    1. Create an HTML.Helper to iterate through this item and render in your View.

      public static MvcHtmlString SideBarItens(this HtmlHelper helper, IDictionary<string, string> model)
          {
              var stringBuilder = new StringBuilder();
      
              foreach (var item in model)
                  stringBuilder.Append(string.Format("<li><a href=\"/{0}\">{1}</a></li>", item.Key, item.Value));
      
              return MvcHtmlString.Create(stringBuilder.ToString());
          }
      
    2. Create an Action for this Menu, with [ChildActionOnly] attribute, the responsability of this Action is to get user's profile, and according to that, get menu items for this profile, and pass this values to your Partial View. You can create a Dictionary to pass action frendly name to render in your HTML, and value the route for that action. Ex: new Dictionary{{"New Products", "Products/New"}}

    3. In your _Layout or any Default shared view that you have, you call your ChildAction.

      <div class="container-fluid" style="margin-top: 50px;">
          <div class="row">
              @Html.Action("Menu", "Base")
              <div class="col-sm-9 col-md-10 main">
                  <ol class="breadcrumb" style="margin-top: 20px">
                      <li><a href="/Home">Home</a></li>
                  </ol>
                  @RenderBody()
              </div>
          </div>
      
    4. Your Action for that

      [HttpGet, ChildActionOnly]
      public ActionResult Menu()
      {
           //Your logic to fill Dictionary and then returns
           return PartialView(dictionary)
      }
      
    5. And finally you create a View to your menu, that receives your Dictionary as Model and call your Helper.

            @model IDictionary<string, string>    
            <li> 
                <ul class="nav-sidebar">
                    @Html.SideBarItens(Model)
                </ul>
            </li>  
      

    PS: I recommend you to Cache your Menu Action