如何在布局中显示内容
How to show something in Layout
我有一个标准的 ASP.NET MVC 应用程序,带有布局页面和许多视图。例如,对于某些用户(取决于他们的属性或其他原因)我想显示一些东西(即附加菜单)。
布局页面:
@if (Request.IsAuthenticated && User.IsInRole("Admin"))
{
<li class="dropdown">
<a aria-expanded="false" class="dropdown-toggle" role="button" href="#" data-toggle="dropdown">Admin <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>@Html.ActionLink("Users", "Index", "User")</li>
/* ............ */
</ul>
</li>
}
else if (SomeParameter == "SomeValue") // I WANT TO HAVE THIS VARIABLE FOR ALL PAGES
{
/* ............ */
}
如何实现?当然可以:
- 向每个方法添加类似 ViewTag.SomeParameter = "SomeValue" 的内容。但我认为没有必要描述为什么这种方法不好
添加到每个控制器方法:
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
ViewTag.SomeParameter = "SomeValue";
}
这个方法也不好,尤其是当我们有10个以上的控制器时,这些控制器的视图都使用这个Layout。
哪种方法好?
实施基本视图模型。让所有相关的视图模型都继承自基础。将布局的模型指定为基础视图模型。我将使用布尔值,但您可以使用字符串。
ViewModel
public class BaseViewModel
{
public bool CanSeeSecondaryMenu {get;set;}
}
布局
@model Web.BaseViewModel
...
else if (Model.CanSeeSecondaryMenu) // I WANT TO HAVE THIS VARIABLE FOR ALL PAGES
{
/* ............ */
}
动作
public ActionResult Index()
{
var model = new InheritedFromBaseViewModel { CanSeeSecondaryMenu = //Set via logic };
return View(model);
}
如果您想概括设置此布尔值的逻辑,您可以创建一个基本控制器,让所有相关控制器继承它,并覆盖 OnActionExecuting
方法
public abstract class BaseController : Controller
{
protected bool CanSeeSecondaryMenu { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
CanSeeSecondaryMenu = //Set via logic
}
}
然后 Index 动作会变成这样...
public ActionResult Index()
{
var model = new InheritedFromBaseViewModel { CanSeeSecondaryMenu = CanSeeSecondaryMenu };
return View(model);
}
我有一个标准的 ASP.NET MVC 应用程序,带有布局页面和许多视图。例如,对于某些用户(取决于他们的属性或其他原因)我想显示一些东西(即附加菜单)。
布局页面:
@if (Request.IsAuthenticated && User.IsInRole("Admin"))
{
<li class="dropdown">
<a aria-expanded="false" class="dropdown-toggle" role="button" href="#" data-toggle="dropdown">Admin <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>@Html.ActionLink("Users", "Index", "User")</li>
/* ............ */
</ul>
</li>
}
else if (SomeParameter == "SomeValue") // I WANT TO HAVE THIS VARIABLE FOR ALL PAGES
{
/* ............ */
}
如何实现?当然可以:
- 向每个方法添加类似 ViewTag.SomeParameter = "SomeValue" 的内容。但我认为没有必要描述为什么这种方法不好
添加到每个控制器方法:
protected override void Initialize(System.Web.Routing.RequestContext requestContext) { base.Initialize(requestContext); ViewTag.SomeParameter = "SomeValue"; }
这个方法也不好,尤其是当我们有10个以上的控制器时,这些控制器的视图都使用这个Layout。
哪种方法好?
实施基本视图模型。让所有相关的视图模型都继承自基础。将布局的模型指定为基础视图模型。我将使用布尔值,但您可以使用字符串。
ViewModel
public class BaseViewModel
{
public bool CanSeeSecondaryMenu {get;set;}
}
布局
@model Web.BaseViewModel
...
else if (Model.CanSeeSecondaryMenu) // I WANT TO HAVE THIS VARIABLE FOR ALL PAGES
{
/* ............ */
}
动作
public ActionResult Index()
{
var model = new InheritedFromBaseViewModel { CanSeeSecondaryMenu = //Set via logic };
return View(model);
}
如果您想概括设置此布尔值的逻辑,您可以创建一个基本控制器,让所有相关控制器继承它,并覆盖 OnActionExecuting
方法
public abstract class BaseController : Controller
{
protected bool CanSeeSecondaryMenu { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
CanSeeSecondaryMenu = //Set via logic
}
}
然后 Index 动作会变成这样...
public ActionResult Index()
{
var model = new InheritedFromBaseViewModel { CanSeeSecondaryMenu = CanSeeSecondaryMenu };
return View(model);
}