我需要把几个下拉菜单上我的应用程序的右上方。 这些菜单必须出现在使用该布局的每个页面上。
唯一的问题是,菜单项目从数据库中抽取。
通常我会在列表传递给像这样的模型
public ActionResult Clients()
{
using (SomeContext db = new SomeContext())
{
var clients = db.Database.SqlQuery<Client>("SELECT * FROM clients").ToList();
return View(clients);
}
}
但是,我不知道怎么做同样的事情,而无需编写每个视图相同的代码。 我只想写下面这段代码一次,但不担心有写对每个视图相同的代码。
什么是有一个全球性的下拉菜单中我的应用程序的正确方法?
我更喜欢使用一个控制器来使我的菜单。 这提供了高速缓存,再利用和逻辑用于菜单(例如显示或不显示基于角色/权利要求中的菜单)。 你可以阅读完整文章菲尔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>();
}
}
现在,如果你想在这每一个页面,只需在全球注册了。 您可以在做到这一点RegisterRoutes
的方法RouteConfig
类
public static void RegisterRoutes(RouteCollection routes)
{
//Existing route definitions goes here
GlobalFilters.Filters.Add(new LoadMenu());
}
现在,在您的布局文件,阅读菜单的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
需要。
文章来源: How can I create a global menu for my application whith its items pulled from a database?