_ViewStart.cshtml 布局文件在哪里以及如何链接?

Posted

技术标签:

【中文标题】_ViewStart.cshtml 布局文件在哪里以及如何链接?【英文标题】:Where and how is the _ViewStart.cshtml layout file linked? 【发布时间】:2012-03-07 05:01:39 【问题描述】:

这是来自默认 MVC 3 模板的 About.cshtml

@
    ViewBag.Title = "About Us";


<h2>About</h2>
<p>
     Put content here.
</p>

我希望在About.cshtml 中可以找到对_ViewStart 文件的引用,但显然不是。

我查看了global.asaxweb.config,但我找不到About.cshtml 文件是如何与_ViewStart 文件中的布局“链接”的。

一切都按预期工作,我只是想知道引擎盖下发生了什么......

【问题讨论】:

【参考方案1】:

来自ScottGu's blog:

从 ASP.NET MVC 3 Beta 版本开始,您现在可以添加文件 在 项目的 \Views 文件夹:

_ViewStart 文件可用于定义您可以使用的通用视图代码 想要在每个视图的渲染开始时执行。例如, 我们可以在 _ViewStart.cshtml 文件中编写代码 以编程方式将每个 View 的 Layout 属性设置为 默认为 SiteLayout.cshtml 文件:

因为这段代码在每个视图的开头执行,我们不再 需要在我们的任何单个视图文件中显式设置布局 (除非我们想覆盖上面的默认值)。

重要提示:因为 _ViewStart.cshtml 允许我们编写代码,所以我们 可以选择使我们的布局选择逻辑更丰富,而不仅仅是 基本属性集。例如:我们可以改变布局模板 我们使用的设备取决于访问网站的设备类型 – 并为这些设备提供优化的手机或平板电脑布局,以及 PC/笔记本电脑的桌面优化布局。或者,如果我们正在构建一个 跨多个客户使用的 CMS 系统或公共共享应用程序 我们可以根据客户(或 他们的角色)访问网站时。

这使得 UI 具有很大的灵活性。它还可以让您更 轻松编写一次视图逻辑,避免多次重复 地方。

另见this。

【讨论】:

所以它或多或少是 MVC3 的“硬编码”功能?我不需要将其更改为另一个“默认”页面,只是好奇它是如何设置的。谢谢你整理出来:) Kman- 硬编码,按照惯例(在此处选择另一个“句柄”:))- 是的,完全正确。很高兴它驱散了雾 您可能不仅需要它在“视图”文件夹中。如果添加自定义 RazorViewEngine 以便将视图组织到其他文件夹中,则还必须将文件包含在这些备用视图文件夹的根目录中。例如,我将所有 Inspinia 模板视图移动到一个文件夹中,并在视图引擎 ViewLocationFormats = ViewLocationFormats.Union(new string[] "~/Inspinia/ExampleViews/1/0.cshtml" ).ToArray(); 中运行它。结果,我不得不将我的 _ViewStart.cshtml 文件的副本添加到“~/Inspinia/ExampleViews”,否则它没有被拾取并且没有设置任何布局。 如果您的 Views 文件夹有子文件夹,您可以在每个子文件夹中放置一个_ViewStart 以链接到该子文件夹中的视图吗?【参考方案2】:

在更一般的意义上,MVC 框架“了解”_Viewstart.cshtml 的这种能力称为"Coding by convention".

约定优于配置(也称为约定编码)是 一种软件设计范式,旨在减少 开发人员需要做出的决定,获得简单性,但不是 必然失去灵活性。这句话本质上意味着一个 开发人员只需要指定非常规方面 应用。例如,如果模型中有一个类 Sale,则 数据库中对应的表默认为“sales”。它 仅当偏离此约定时,例如调用 表“products_sold”,需要编写有关这些的代码 名字。

***

它没有魔法。它刚刚被写入 MVC 框架的核心代码库,因此是 MVC“知道”的东西。这就是为什么您在 .config 文件或其他地方找不到它的原因;它实际上在 MVC 代码中。但是,您可以覆盖以更改或取消这些约定。

【讨论】:

如果 MVC 知道这件事,那么为什么 Visual Studio 不知道并向我指出这一点?如果按照约定进行编码意味着只要您碰巧不违反约定,这些东西就可以工作,那有点糟糕... 不打破常规是重点。 AKAIK Ruby on Rails 也遵循这种范式。 +1 雷夫。为记录不充分的“按惯例编码”辩护是没有意义的。我可以这样说我的任何反向代码。 “什么?你没想到它到了33就崩溃了?大家都知道你跳过33。”不幸的是,ASP.NET MVC 的文档差距很大。唯一的 MS 文档是自动生成的,没有内部源摘要。 约定优于配置并不意味着你不能改变它。应该有可用的配置来指定该文件的名称和位置。很可能有,但谁知道它是什么。人们使用“约定优于配置”的口头禅来涵盖代码库中的大量错误决策,这让我很生气,因为我是事后才来维护他们“正常工作”的记录不充分的混乱(但是上帝保佑你改变任何东西——你会花几个小时弄清楚你是如何破坏一切的)。 @AidenStrydom 我不同意。接受的答案实际上告诉我如何使用 _ViewStart。这个答案只是谈论一个设计概念。我来这里是为了获取关于 _ViewStart 的信息,而不是关于为什么 Visual Studio 不会告诉我关于 _ViewStart 的任何信息。【参考方案3】:

只是另一个想法。

如果你想拥有自己的cshtml文件作为通用模板,你可以这样做

在您的_viewstart.cshtml 中,您可以提及您常用的cshtml 文件。

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

【讨论】:

【参考方案4】:

源代码比文档更适合查找。

引用 Github 中的 MVC 6 code,我们有一些感兴趣的文件

----更新----

由于源结构发生变化,有关如何收集 viewstart 页面的信息现在可以在 RazorViewEngine.cs 查找“GetViewStartPages”函数中找到。

----/更新----

要回答它们是如何发挥作用的,请查看 RazorView,我相信(因为 IView)与 MVC 管道相关联。此文件有一个 RenderAsync 方法,该方法从 MVC 管道调用以呈现请求的视图。

RenderAsync 调用 RenderPage,然后调用 RenderLayout(注意顺序)。 RenderPage 首先调用处理 viewstart 文件(注意复数,可能有多个 _viewstart 文件)。

因此,您可以从 Microsoft.AspNet.Mvc.Razor 命名空间下RazorView.cs 文件中的 RenderViewStartAsync 函数中获取您要查找的信息。

【讨论】:

【参考方案5】:

这可能会为这个问题添加一些附加信息(2016 ala MVC4、MVC5)。

Razor 引擎会先于 _ViewStart.cshtml 中的任何其他代码在找到 _ViewStart.cshtml 的同一目录或子目录中查找并运行该代码。

任何视图都可以覆盖 Layout 属性或其任何值。

只是想我可能会添加更多信息来向您展示它为什么是 _ViewStart。

如果您获得 ILSpy 并检查 RazorViewEngine (System.Web.Mvc.dll) 中的代码,您将看到代码本身引用了该名称。

您可以看到 RazorViewEngine 查找具有该名称的文件:

RazorViewEngine.ViewStartFileName = "_ViewStart";

【讨论】:

这就是我要找的东西,我讨厌“不知道”我的项目中发生了什么,因为我也在为 VS 和这个刚刚从空中出现的文件做自己的模板很不方便理解【参考方案6】:

如果你想为你的页面有一个通用布局,你需要定义通用布局并将视图与布局相关联,我们必须在每个视图上设置布局属性,这违反了 DRY(不要重复自己) 原则。 为此 .Net Framework 提供了“_ViewStart.cshtml”文件,放置在视图文件夹中。 我们将布局信息放在“_ViewStart.cshtml”文件中,默认情况下每个视图都使用此布局信息。 如果您想提供一些不同的布局信息,假设您的主视图,您可以参考该布局创建一个新的“_ViewStart.cshtml”并将其放在“主视图”文件夹中。

【讨论】:

【参考方案7】:

简短的回答是: ViewStarts 在渲染任何视图时首先启动。长篇大论如下:

创建单一视图文件的故事:

    ViewStart 与 ViewImports 合并,然后作为单个文件执行。请注意,ViewImports 始终与任何 cshtml 文件合并,包括 ViewStart 文件。其目的是抽象@using 语句和其他常用指令。 ViewStart 的输出(例如 Layout 和 ViewData)变得可用于特定的 View 文件。 在 View 文件中,如果 Layout 变量为/变为 null,则呈现视图主体并将最终输出传递给用户。 如果 Layout 变量不为空,则执行将移至布局文件,该文件又与 ViewImports 合并为单个文件,然后在布局文件内的 @RenderBody() 语句处执行移回视图文件再次与 ViewImports 合并,输出与 @RenderBody() 位置的布局文件合并,最终输出给用户。

希望这能让您了解程序生命周期的未知奥秘中到底发生了什么。

【讨论】:

以上是关于_ViewStart.cshtml 布局文件在哪里以及如何链接?的主要内容,如果未能解决你的问题,请参考以下文章

十一:模板页面

[九] ASP.NET CoreMVC 中的布局视图

我可以防止共享布局用于错误消息吗?

C#之razor

我的设置活动的布局文件在哪里?

在哪里以及如何找到 Android 类使用的布局文件?