如何使用从数据库中提取的项目为应用程序创建全局菜单

本文关键字:应用程序 创建 全局 菜单 项目 何使用 数据库 提取 | 更新日期: 2023-09-27 17:58:18

我需要在应用程序的右上角放置几个下拉菜单。这些菜单需要出现在使用该布局的每一页上。

唯一的问题是菜单项是从数据库中提取的。

通常我会把清单传给这样的模特

public ActionResult Clients()
{
   using (SomeContext db = new SomeContext())
   {
       var clients = db.Database.SqlQuery<Client>("SELECT * FROM clients").ToList();
       return View(clients);
   }
}

但是,如果不必为每个视图编写相同的代码,我不知道如何做同样的事情。我只想在下面写一次代码,而不用担心必须为每个视图写相同的代码。

为我的应用程序提供全局下拉菜单的正确方法是什么?

如何使用从数据库中提取的项目为应用程序创建全局菜单

我更喜欢使用控制器来呈现我的菜单。这为菜单提供了缓存、重用和逻辑(比如根据角色/声明显示或不显示菜单)。您可以阅读Phil Haacked的完整文章-Html.RenderAction和Html.Action,摘录如下。

c#

public class MenusController {
  [ChildActionOnly]
  public ActionResult MainMenu() {
    var menu = GetMenuFromSomewhere();
   return PartialView(menu);
  }
}

Html:

<html>
<head><title></title></head>
<body>
  @Html.Action("MainMenu", "Menus")
  <h1>Welcome to the Index View</h1>
</body>
</html>

您可以创建一个操作过滤器来执行此操作。

public class LoadMenu : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var vb = filterContext.Controller.ViewBag;
        var menu = new List<MenuItem>();
        //I am hard coding to 2 items here. You may read it from your db table
        menu.Add(new MenuItem() { Text = "Home", TargetUrl = "Home/Index" });
        menu.Add(new MenuItem() { Text = "Careers", TargetUrl = "Home/Careers" });
        vb.Menus = menu;
    }
}

假设您有一个名为MenuItem 的类

public class MenuItem
{
    public string Text { set; get; }
    public string TargetUrl { set; get; }
    public List<MenuItem> Childs { set; get; }
    public MenuItem()
    {
        this.Childs = new List<MenuItem>();
    }
}

现在,如果你想在每个页面上都有这个,只需在全局范围内注册即可。您可以在RouteConfig类中的RegisterRoutes方法中执行此操作

public static void RegisterRoutes(RouteCollection routes)
{
  //Existing route definitions goes here
   GlobalFilters.Filters.Add(new LoadMenu());
}

现在在布局文件中,读取名为Menus的ViewBag项目,并根据需要构建菜单标记。

@{
    var menu = ViewBag.Menus as List<MenuItem>;
    if (menu != null)
    {
        foreach (var m in menu)
        {
            <li><a href="@m.TargetUrl">@m.Text</a></li>
        }
    }
}

您可以根据需要更新以上代码以渲染Childs