applying security among menus

2019-09-02 15:03发布

问题:

below is my model

public class security
{  
    public long id { get; set; }
    public long user_id { get; set; }
    public long submenu_id { get; set; }
    public bool flag { get; set; }

}

it the flag is true the user has access to submenu.

Currently what i am doing is . When the user logged in the details in this model will be pulled out and store in seperate session variable.

eg: - var c = db.security.where(m=> m.user_id == id).Orderby(id);

if(c.submenu_id == 1 && c.flag == true)
   session["mem_add"] = "true";
else
   session["mem_add"] = "false";

Then in the layout view will check this session variable and if true the menu will display, but problem is there are 16 sub menus and can increase it later.So I have to create seperate session variables for each submenu. Is there any better way to solve this problem?

Edited

@if(Session["mem_add"] == "true")
{
          <li class="active"><a href="@Url.Action("Index", "UpdateDetail")">
            <img src="@Url.Content("~/Images/Enrollments.png")" alt=""><span class="title"><b>
    @Resources.Resources.UpdateMyDetail</b> </span> </a></li>
}

回答1:

I would suggest a view model approach to represent your menu items

public class MenuItem
{
  public int ID { get; set; }
  public string ControllerName { get; set; }
  public string ActionName { get; set; }
  public string LinkText { get; set; }
  public string ImageUrl { get; set; }
  public bool CanView { get; set; }
}

Then when a user logs in, create a collection of menu items, call your method to get the security items for the user, and based on the flag property, set the CanView property for each menu. Finally store the collection in Session

Then create a child only method to generate your menu

[ChildActionOnly]
public ActionResult Menu
{
  IEnumerable<MenuItem> model = Session["Menu"] as IEnumerable<MenuItem>;
  // check for null and rebuild if necessary
  return PartialView("_Menu", model);
}

and create a partial view _Menu.cshtml

@model IEnumerable<yourAssembly.MenuItem>
<ul>
  @foreach(var menu in Model)
  {
    if (menu.CanView)
    {
      <li>
        <a href=""@Url.Action(menu.ActionName, menu.ControllerName)">
          <img src="@Url.Content(menu.ImagePath)" alt="">
          <span class="title"><b>menu.LinkText</b></span> 
        </a>
      </li>
    }
  }
</ul>

and finally in the layout page, use Html.Action() to call the method that generates the menu items

@Html.Action("Menu", yourControllerName)


回答2:

Your other option would be to create an extension to HtmlHleper, then you can use it to pass a model to your menu and let it generate an MvcHtmlString

public MvcHtmlString CreateMenu(this HtmlHelper helper, MenuSecurityModel)
{
   //create tags, string, etc
   //create logic add/remove meun items depending on flag property on model
   //this can be accomplished also by using a base class for your Controllers, 
   //set the the onactionexecuting variable to set the menu[ put it in session accodingly, retrieve when appropriate
   //Call using Html.RenderAction , partial, etc
   return yourHtmlString;
}