所以我浏览了一下,似乎无法找到解决问题的合适方法。
问题
在我的布局中,我希望能够根据数据库中的内容选择运行时是否存在导航项:
当前布局(导航栏)
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Dashboard", "Index", "Dashboard")</li>
<li>@Html.ActionLink("NzbGet", "Index", "NzbGet")</li>
<li>@Html.ActionLink("Plex", "Index", "Plex")</li>
<li>@Html.ActionLink("Settings", "Index", "Settings")</li>
</ul>
</div>
我如何决定看哪一个展示:
public PrincipleExtension(ISettingsService<SabNzbSettingsDto> sab)
{
SabService = sab;
}
private ISettingsService<SabNzbSettingsDto> SabService { get; set; }
public bool IsApplicationEnabled(IPrincipal principal, Applications application)
{
switch (application)
{
case Applications.SabNZBD:
return SabService.GetSettings().Enabled;
//...
}
return false;
}
现在,PrincipleExtension
最初是IPrincipal
上的扩展方法。但现在这是不可能的,因为我使用的是IoC容器,并且不想对任何依赖项进行硬编码。
所以在它是静态方法之前我可以做User.IsApplicationEnabled(Applications.SabNZBD)
。
如何在布局中检查应用程序是否已将启用标志设置为true?有什么想法吗?
感谢。
答案 0 :(得分:2)
将菜单HTML移动到PartialView,并将其作为ActionResult从Controller Action返回。
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@foreach (var item in Model)
{
<li><a href="@item.Url">@item.Name</a></li>
}
</ul>
</div>
让控制器确定哪些菜单项存在并将新模型发送到PartialView。
public ActionResult ProductsMenu()
{
var listOfAvailableProducts = GetAvialableProducts(Principal); //to implement elsewhere
var productsMenuItems = new List<ProductMenuItem>();
for(var i in listOfAvailableProducts)
{
productsMenuItems.Add(new ProductMenuItem
{
Id = i.id,
Name = i.name,
Url = "//example.com/there"
}
);
}
return PartialView("/path/to/_ProductsMenu.cshtml", productsMenuItems);
}
然后在_Layout.cshtml razor视图中调用它:
@{
Html.RenderAction("ActionName","ControllerName");
}
答案 1 :(得分:1)
您可能需要查看名为MVCSitemapProvider的nuget包。
它具有引导程序互操作性,您可以使用它在运行时动态生成导航,使您可以在任何给定时间检查导航的状态/状态。
此链接显示您可以随时动态生成导航节点:
public class StoreDetailsDynamicNodeProvider
: DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
using (var storeDB = new MusicStoreEntities())
{
// Create a node for each album
foreach (var album in storeDB.Albums.Include("Genre"))
{
DynamicNode dynamicNode = new DynamicNode();
dynamicNode.Title = album.Title;
dynamicNode.ParentKey = "Genre_" + album.Genre.Name;
dynamicNode.RouteValues.Add("id", album.AlbumId);
yield return dynamicNode;
}
}
}
}
这种方法的另一个好处是它带回了Sitemap.xml-esque功能,允许您同时分配静态和动态导航。
这是我的菜单displaytemplate的一个例子:
@model MenuHelperModel
<div class="navbar navbar-inverse navbar-static-top hidden-print">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navContainer">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="~/" class="navbar-brand">AH Operations <i class="glyphicon glyphicon-home"></i></a>
</div>
<div class="collapse navbar-collapse" id="navContainer">
<ul class="nav navbar-nav" role="menu" aria-labelledby="dropdownMenu">
@foreach (var node in Model.Nodes)
{
if (node.Title == "Separator")
{
<li class="nav-divider"></li>
}
else if (node.Children.Any())
{
if (node.IsCurrentNode || node.IsInCurrentPath)
{
<li class="active dropdown">
@Html.DisplayFor(m => node)
@Html.DisplayFor(m => node.Children)
</li>
}
else
{
<li class="dropdown">
@Html.DisplayFor(m => node)
@Html.DisplayFor(m => node.Children)
</li>
}
}
else
{
if (node.IsCurrentNode || node.IsInCurrentPath)
{
<li class="active">
@Html.DisplayFor(m => node)
</li>
}
else
{
<li>
@Html.DisplayFor(m => node)
</li>
}
}
}
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
要使其与Bootstrap 3中删除的无限n + 1子菜单样式一起使用,请添加此CSS:
.navbar-user {
font-size: 14px !important;
}
.dropdown-submenu {
position: relative;
}
.dropdown-submenu > .dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.dropdown-submenu > a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #cccccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover > a:after {
border-left-color: #ffffff;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left > .dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}
答案 2 :(得分:0)
我将创建一个全局ActionFilter并覆盖OnActionExecuting方法,以便在每个请求的ViewBag中放置您的标志。您还可以创建一个HtmlHelper扩展方法。