Asp.net core mvc 如何在ASP.NET核心MVC中指定不同的布局
我想在我的应用程序中有2个单独的布局。假设一个是网站的公共部分,另一个是空的,因为我们需要的一些原因 在Core之前,我可以这样定义一个过滤器:Asp.net core mvc 如何在ASP.NET核心MVC中指定不同的布局,asp.net-core-mvc,Asp.net Core Mvc,我想在我的应用程序中有2个单独的布局。假设一个是网站的公共部分,另一个是空的,因为我们需要的一些原因 在Core之前,我可以这样定义一个过滤器: public class LayoutInjecterAttribute : ActionFilterAttribute { private readonly string _masterName; public LayoutInjecterAttribute(string masterName) { _mast
public class LayoutInjecterAttribute : ActionFilterAttribute
{
private readonly string _masterName;
public LayoutInjecterAttribute(string masterName)
{
_masterName = masterName;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var result = filterContext.Result as ViewResult;
if (result != null)
{
result.MasterName = _masterName;
}
}
}
现在ViewResult没有MasterName属性。是否可以立即执行此操作,而不在视图中使用布局定义。您可以使用
IViewLocationExpander
界面根据需要渲染视图。
有关更多详细信息,请参阅此链接
问候,
Rohit这就是我在ASP.NET核心MVC应用程序中使用多个布局的方式 你可以这样试试-
@{
Layout = "_Layout";
}
@{
Layout = "~/Views/Shared/_Layout_2.cshtml";
ViewData["Title"] = "Page Title";
}
在\u ViewStart.cshtml
中指定如下默认布局-
@{
Layout = "_Layout";
}
@{
Layout = "~/Views/Shared/_Layout_2.cshtml";
ViewData["Title"] = "Page Title";
}
如果要设置特定于页面的布局,则可以在该page.cshtml
中指定其他类似的视图-
@{
Layout = "_Layout";
}
@{
Layout = "~/Views/Shared/_Layout_2.cshtml";
ViewData["Title"] = "Page Title";
}
看看这是否有帮助。您仍然可以执行与原始方法非常类似的操作,使用
ViewData
传递布局名称(尽管我会将其创建为:
然后在\u ViewStart.cshtml
文件中:
@{
Layout = (string)ViewData["Layout"] ?? "_Layout";
}
@{
if (some condition)
{
Layout = "_Layout1";
}
else if (some other condition)
{
Layout = "_Layout2";
}
etc.
}
最后,假设您创建了一个新的布局,如Views/Shared/_CleanLayout.cshtml
,您可以在任何控制器或操作上使用该属性:
[ViewLayout("_CleanLayout")]
public IActionResult About()
{
//...
}
如果您想根据某些条件使用不同的布局,可以在
\u ViewStart.cshtml
文件中使用以下代码:
@{
Layout = (string)ViewData["Layout"] ?? "_Layout";
}
@{
if (some condition)
{
Layout = "_Layout1";
}
else if (some other condition)
{
Layout = "_Layout2";
}
etc.
}
我在我的一个项目中使用它。在我的情况下,条件是User.IsInRole(“admin”),我的\u ViewStart.cshtml
文件如下所示:
@{
if (User.IsInRole("admin"))
{
Layout = "_AdminLayout";
}
else
{
Layout = "_Layout";
}
}
因为在我的项目中只有两个角色,这只会导致一种情况,所以在我的情况下,这种变通方法并不太糟糕。我希望有类似情况的人会发现这一点很有用:)在ASP.NET Core 2.0中,@Daniel J.G.的答案启发了我 我制作了一个
ViewLayoutAttribute
:
[AttributeUsage(AttributeTargets.Class)]
公共类ViewLayoutAttribute:属性
{
公共视图布局属性(字符串布局名称)
{
this.LayoutName=LayoutName;
}
公共字符串LayoutName{get;}
}
控制器类的示例:
[ViewLayout(“\u Layout2”)]
公共类MyController:Controller
{
//代码
}
我创建了一个扩展来从ViewContext
获取这个属性:
公共静态类RazorExtensions
{
///
///从的当前调用控制器获取
/// .
///
公共静态ViewLayoutAttribute GetLayoutAttribute(此ViewContext ViewContext)
{
//看看页面是否。。。
如果(viewContext.ActionDescriptor为CompiledPageActionDescriptor ActionDescriptor)
{
//无论发生什么,我们都需要属性。
返回Attribute.GetCustomAttribute(actionDescriptor.ModelTypeInfo,typeof(ViewLayoutAttribute))作为ViewLayoutAttribute;
}
//查看MVC控制器是否。。。
//在运行时可以看到Property ControllerTypeInfo。
变量controllerType=(类型)viewContext.ActionDescriptor
.GetType()
.GetProperty(“ControllerTypeInfo”)?
.GetValue(viewContext.ActionDescriptor);
if(controllerType!=null&&controllerType.IsSubclassOf(typeof(Microsoft.AspNetCore.Mvc.Controller)))
{
返回Attribute.GetCustomAttribute(controllerType,typeof(ViewLayoutAttribute))作为ViewLayoutAttribute;
}
//什么也没找到。
返回null;
}
}
在\u ViewStart.cshtml
中:
@using MyApp.Extensions
@{
Layout = ViewContext.GetLayoutAttribute()?.LayoutName ?? "_Layout";
}
要在asp.net core中具有多个布局非常简单,请执行以下步骤: 步骤1:在“位于视图下的共享文件夹”中创建布局,并给它一个前缀为“u”的名称,即
\u myLoginLayout.cshtml
第2步:在要应用布局的页面开头指定布局,例如
@{Layout=“~/Views/Shared/\u myLoginLayout.cshtml”ViewData[“Title”]=“TestMe”
//您也可以添加标题。。。
}
因此,当
\u ViewStart.cshtml
为您的页面加载布局时,它将读取您指定的布局。Thx,但这不是我想要的。但这个想法很有趣。我是这样做的,但我不喜欢这种方式。它并不优雅。对我来说是可行的,另一种方法似乎很麻烦。如何在应用程序开始时在viewStart中获取用户对象?如果您使用的是Razor,它在默认情况下应该是可用的。intellisense甚至应该提出这个建议(我知道这是在Visual Studio 2015+中)。如果您在访问时遇到问题,请告诉我,以便我可以帮助您这正是我想要做的,只是我想为用户会话缓存User.IsInRole(“admin”)的结果,这样它就不会为每个请求触发(让它在会话中为每个后续请求检索它)。我已经实现了我自己的“SessionCacheService”,其中我有一些预定义的会话变量,该服务在ViewStart.cshtml文件中是否可用?将此服务的依赖项注入放在ViewStart.cshtml中?您可以使用“@”从视图中引用项目中的任何类。假设您的项目“MyProject”在名为“Cache”的文件夹中有“SessionCacheService”;您可以使用“@MyProject.Cache.SessionCacheService”在任何视图(包括ViewStart.cshtml)中引用它。这有帮助吗?谢谢-这是对asp.net核心mvc过滤器/mvc生命周期的一个非常好的介绍-并且一次性解决了我的问题。这对我帮助很大!