【问题标题】:Strange error with rendering scripts on layout page在布局页面上呈现脚本的奇怪错误
【发布时间】:2015-09-05 12:30:29
【问题描述】:

我的_Layout.cshtmlbody 元素的最后一行是:

@RenderSection("Scripts", required: false)

然而,当我运行我的应用程序时,我得到了异常:

以下部分已定义但尚未呈现 对于布局页面“~/Views/Shared/_Layout.cshtml”:“脚本”。

很奇怪,因为Scripts 不是必需的。然后,在我的登录页面中,我注释掉以下行:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

应用程序运行良好。这是不是因为jqueryval 包是空的,所以视图引擎认为Scripts 部分没有在_Layout.cshtml 中呈现?我的BundleConfig 包含有问题的脚本,它存在于我的Scripts 文件夹中,那么可能有什么问题?

【问题讨论】:

  • 我无法重现这个。您是否碰巧有嵌套的布局页面(可能会引发该错误)

标签: asp.net-mvc razor asp.net-mvc-5 bundling-and-minification


【解决方案1】:

我们认为您知道在 MVC 模板中正常工作的部分必备条件。这种奇怪的错误发生在当您在页面中有另一个错误(与RenderSection 没有真正相关)并且框架反映错误错误而不是显示主要错误时。看看my recent issue,它来自相关页面中未定义和使用的ViewBag.sth。或者另一个例子可能是this post,所有者有时会遇到手机错误!最后一个的答案是一样的,我认为所有者使用变量可能是通过浏览器帮助填充页面上的数据,并且在完成页面渲染之前它们还没有准备好时会发生错误。 简单地说,当视图变量未准备好(未枚举或初始化)时,会发生这种不相关的错误并且调试器向我们显示了一个奇怪的错误。因此,您在页面呈现期间使用了一个未分配和已使用的变量。

解决方案:检查页面中使用的变量(动态变量,如ViewBagViewData),从主布局文件跟踪到最终呈现的页面(包括部分视图)以找出什么发生了。

【讨论】:

    【解决方案2】:

    这必须有效:

    @RenderSection("Scripts", false)
    

    您还可以将 @RenderSection 包装在 if 块中:

    @if (IsSectionDefined("scripts"))
    {
        RenderSection("scripts");
    }
    

    更新:确保RenderSection 与您的视图中定义的部分具有相同的名称,例如在您的_Layout 中您应该具有以下RenderSection

    @RenderSection("Scripts", required: false)
    

    在其他观点中:

    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }
    

    如果名称(在本例中为 Scripts)不匹配,则会引发该错误:

    以下部分已定义但尚未呈现 对于布局页面“~/Views/Shared/_Layout.cshtml”:“脚本”。

    另外,请确保您的 _ViewStart.cshtml 指向正确的布局:

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

    【讨论】:

    • 正常的@RenderSection("Scripts", false) 不起作用,我问这个问题是为了找出原因,而不是像第二个例子那样解决它。如果Scripts 是可选的,MVC 运行时应该执行@if (IsSectionDefined("scripts")),而不是我。但是谢谢,如果我没有及时赶到,我可能会使用解决方法。
    【解决方案3】:

    似乎布局页面正在从_ViewStart 呈现,而不是直接在您的View 上引用。请确保您的View 上直接引用了_Layout,即:

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

    【讨论】:

    • 我为什么要这样做?那么_ViewStart的目的是什么?
    • ViewStart 是派生自 ViewStartPage 而不是其他视图派生自 WebViewPage 的特殊视图。而ViewStartPage 类没有DefineSection 方法。所以你不能在这个文件中定义部分。
    • RenderSection 只能使用由使用它们的视图立即定义的部分。由于_ViewStart 在任何视图请求代码运行之前运行,这就是它在那里不可用的原因。这是设计使然。目前Razor 布局只能使用(渲染)sections 由使用它们的view 立即定义。您不能有布局页面的层次结构,并且在最外层布局中使用在最内层 view 中定义的 section
    【解决方案4】:

    我将其发布为答案,因为我没有足够的积分来对您的问题发表评论。对不起。

    但是你确定,你的登录页面是同一个布局页面吗?

    【讨论】:

      【解决方案5】:

      改变

      @section Scripts {
          @Scripts.Render("~/bundles/jqueryval")
      }
      

      到这里

      @section Scripts
      {
         <script type="text/javascript" src="@Url.Content("~/scripts/jqueryval.js")"></script> 
      }
      

      如果你想在视图页面上渲染脚本你必须设置

      @RenderSection("Scripts", required: true)
      

      【讨论】:

      • 使用script 标签违背了MVC 的整个捆绑和缩小功能的目的,我绝对不想那样倒退。然后,required: true 违背了在我的视图中添加 可选 脚本部分的目的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多