如何在 ASP.NET MVC 3 razor ViewStart 文件中指定不同的布局?

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 3 razor ViewStart 文件中指定不同的布局?【英文标题】:How do I specify different Layouts in the ASP.NET MVC 3 razor ViewStart file? 【发布时间】:2011-07-06 21:24:06 【问题描述】:

我想在我的应用程序中有 2 个单独的布局。假设一个用于网站的公共部分,另一个用于会员方。

为简单起见,假设每个站点的所有逻辑都整齐地包装在 2 个不同的控制器中。

公共控制器 员工控制器

而且它们每个下的所有View都有一个对应的Layout。

_PublicLayout.cshtml _StaffLayout.cshtml

如何使用 _ViewStart.cshtml 文件指定“Public”下的所有 View/Actions 使用 PublicLayout 而“Staff”下的所有内容都使用 StaffLayout?

【问题讨论】:

以防万一:如果您想删除给定Razor 视图的布局,只需设置Layout = null; 就像对您的示例的评论一样,您可能不应该有名为 Public 和 Staff 的控制器。控制器通常被实现为对某些关键业务实体(如 EventController、UserController 等)进行类似 CRUD 的操作的入口点。如果您的应用程序相当大,那么 Public/Staff 控制器的职责范围就会很广。改为考虑区域。 msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx您可能知道这一点,但其他阅读此内容的人可能会得到错误的想法,因此仅作记录。 【参考方案1】:

您可以将_ViewStart.cshtml 文件放在/Views/Public 文件夹中,这将覆盖/Views 文件夹中的默认文件并指定所需的布局:

@
    Layout = "~/Views/Shared/_PublicLayout.cshtml";

以此类推,您可以将另一个 _ViewStart.cshtml 文件放入 /Views/Staff 文件夹中:

@
    Layout = "~/Views/Shared/_StaffLayout.cshtml";

您还可以指定在控制器操作中返回视图时应使用哪种布局,但这是每个操作:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

另一种可能性是自定义操作过滤器将覆盖布局。如您所见,实现这一目标的可能性很多。由您来选择最适合您的场景。


更新:

根据 cmets 部分的要求,这里是一个选择母版页的操作过滤器示例:

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;
        
    

然后用这个自定义属性来装饰一个控制器或一个动作,指定你想要的布局:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()

    return View();

【讨论】:

@DarinDimitrov 我将在哪里创建LayoutInjecterAttribute。 ?有什么特别的地方吗? @VeeKeyBee,你可以把它放在ActionFilters 子文件夹中。 LayoutInjecterAttribute 的一个潜在问题:它在控制器的OnException 方法之前调用。因此,如果控制器在异常处理期间提供了视图结果,则不会设置布局。 作为 MVC 的新手,我想说谢谢你在这个答案中教了我很多东西。但是我不明白OnActionExecuted 内部发生了什么。你能帮我更新一下答案吗?【参考方案2】:

此方法是初学者在 ASP.NET MVC 应用程序中控制布局呈现的最简单方法。我们可以识别控制器并将 Layouts 渲染为 par 控制器,为此我们可以在 Views 文件夹根目录的 _ViewStart 文件中编写代码。下面是一个例子,展示了如何做到这一点。

@
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";
    
    Layout = cLayout;

【讨论】:

【参考方案3】:

另一种方法是在视图中定义布局:

   @
    Layout = "~/Views/Shared/_MyAdminLayout.cshtml";
    

更多方法,可以找到here,希望对大家有所帮助。

【讨论】:

这不起作用 - 如果没有单独的 _ViewStart.cshtml,您的视图仍将在其他布局中的 @RenderBody() 方法内呈现。 这个!为什么大家都在提出这些极其复杂的流程,而您只需要这样做!

以上是关于如何在 ASP.NET MVC 3 razor ViewStart 文件中指定不同的布局?的主要内容,如果未能解决你的问题,请参考以下文章

[Asp.Net Core]MVC_Razor布局

[Asp.Net Core]MVC_Razor布局

如何在 asp.net MVC 4 Razor 中绑定剑道网格

MVC-3 ASP.NET 共享视图-重定向-Razor

如何在 ASP.NET MVC 4 Razor 项目的视图中显示集合?

ASP.net MVC 3 Razor - jQuery Intellisense