【问题标题】:Why have both _ViewStart and _ViewImports? Why not one file?为什么同时具有 _ViewStart 和 _ViewImports?为什么不是一个文件?
【发布时间】:2019-05-04 00:41:31
【问题描述】:

在 ASP.NET Core MVC 中,我们可以将确切名称为 _ViewStart.cshtml 的文件放入文件夹中,以包含要在该文件夹中的每个剃须刀视图/页面之前运行的通用 C# 代码。像这样的:

@{
    const string SomeConstant = "some value";
}

类似地,文件夹中的确切名称为 _ViewImports.cshtml 的文件可以包含所有常见的 razor 指令,以便在该文件夹中的 razor 视图/页面之间共享。像这样:

@layout _Layout
@using MyApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

但有一个问题我无法通过谷歌搜索,无论我如何改写它:

有人可以向我解释为什么我们同时使用_ViewStart.cshtml_ViewImports.cshtml 来定义通用代码和指令吗?为什么这些功能(它们似乎并不相互冲突)不在一个单个文件中定义?

【问题讨论】:

  • 因为一个叫做关注点分离的原则。 ViewImports 关心导入,ViewStart 关心页面/视图所需的逻辑
  • 但是其余的视图关心指令和逻辑和标记......
  • 仅当您愿意时。您可以在一个文件中完成所有操作,包括布局。你做什么只取决于你
  • “只有你想”?抱歉,您的 cmets 似乎比有效的论点包含更多的屈尊俯就……请启发我:我如何在我的其他 .cshtml 文件中坚持这种“称为关注点分离的原则”(您显然只是在教育我) ?您最后一次看到一个不包含指令+标记+一些 c# 全部在一个文件中的实际剃须刀页面是什么时候?这不正是将“剃须刀页面”引入 MVC 堆栈的原因吗? 很抱歉引起愤怒的反弹......
  • Razor Pages 是引起 PHP 用户兴趣的又一次失败尝试,至少微软说,我不会碰它。我有应用程序,其中视图仅用于加载 HTML 和 javascript,其他仅加载 Angular,以及其他包含 HTML 和 Razor。

标签: c# razor asp.net-core asp.net-core-mvc


【解决方案1】:

_ViewStart 文件

它用于在所有视图文件中设置共享内存(公共静态变量)。

例如,ViewStart 的常见做法是为 LayoutViewData / ViewBag设置一个您可以覆盖的默认值> 字典。

_ViewImports 文件

在此文件中,您可以总结(抽象)您在所有视图中常用的所有 using 语句。

为什么要用 _ViewImports 文件代替 ViewStart?

因为 using 指令具有当前视图文件主体的范围。因此,将@using 语句放在 ViewStart 文件中不会使它们可用于除 viewStart 文件本身的主体之外的任何其他视图文件。因此,出现了特殊的 ViewImports 文件,该文件旨在服务于 @using 语句的范围扩展目的和其他有用的东西,例如标签助手,如果没有这个特殊文件,它将在每个违反 @987654321 的视图文件中重复@。

【讨论】:

  • 所以您是说_ViewImports_ViewStart 中范围界定问题的解决方法?我们可能希望将@using 语句放在_ViewStart 中(仅用于_ViewStart 中的逻辑)而不将它们级联到整个文件夹?好吧,感谢您的合理回答,但对我来说,这听起来与 DRY 完全相反:为什么我想要 _ViewStart 中的 @using 声明而不是共享逻辑的其余文件?为什么我需要再次编写相同的 @using 语句才能在其他文件中访问它?
  • @HamidSadeghian,感谢我同意的评论。然而,目前 DRY 原则是这样应用的:_ViewStart 干燥视图的主体,而 _ViewImports 干燥视图的指令部分。 _ViewStart 是公共主体,_ViewImports 是指令的公共标头。从我的角度来看,这样是可以的,因为有时我需要使用一些限制在 _ViewStart 本身范围内的指令。将来可能会改变。
【解决方案2】:

在其他答案中被忽略的一件事是,根据official documentation

  • _ViewStart.cshtml 文件中的代码将对非布局页面运行。
  • _ViewImports.cshtml 文件中的代码将为布局和非布局页面运行。

我已经通过将默认的 Application Insights JavaScript sn-p(下面的代码)从导入文件移动到开始文件来对此进行测试,并且它导致我的布局页面上出现构建错误,因为它无法再找到定义的变量JavaScriptSnippet.

我移动的代码:

@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet

鉴于此,文件之间的区别可能是“我想在任何地方运行的代码”与“我只想为完整视图运行的代码”,类似于.bashrc.bash_profile 之间的区别。

【讨论】:

    【解决方案3】:

    每个页面前需要执行的代码应该放在_ViewStart.cshtml文件中。

    对于 _ViewImport.cshtml - 此文件的内容应用于同一文件夹和子文件夹中的所有文件。

    所以 _ViewStart 是执行,而 _ViewImport 将其内容应用于每个文件。

    测试1_ViewStart 处同时放置“Layout [Correct]”引用和“using statement[Incorrect]”会导致编译器错误。

    测试2_ViewImport 处同时放置“Layout [InCorrect]”参考和“using statement[Correct]”不会将 _Layout 应用于其他页面

    根据MSDN ViewImport 支持以下指令

    @addTagHelper、@removeTagHelper:全部按顺序运行。

    @tagHelperPrefix: 最接近视图的覆盖任何其他的

    @model: 最接近视图的模型会覆盖其他模型

    @inherits: 最接近视图的会覆盖任何其他的

    @using: 都包括在内;重复的被忽略

    @inject:对于每个属性,最接近视图的属性会覆盖具有相同属性名称的任何其他属性

    【讨论】:

      猜你喜欢
      • 2011-08-08
      • 2016-05-09
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 2019-06-01
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多