如何使用从数据库中提取的项目为应用程序创建全局菜单
本文关键字:应用程序 创建 全局 菜单 项目 何使用 数据库 提取 | 更新日期: 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