【问题标题】:Custom WebViewPage inject code when razor template is rendering渲染剃刀模板时自定义 WebViewPage 注入代码
【发布时间】:2015-01-09 12:02:54
【问题描述】:

我正在尝试创建一个自定义 Razor 视图基类(继承 WebViewPage),它将为每个正在呈现的视图模板(包括布局和部分视图)注入一些 HTML,以便我在客户端上有一个参考每个 Razor 模板的开始位置(对它的结束位置不感兴趣)。

到目前为止我尝试过的是

  1. 覆盖Write 方法(如评论here 中所述)。这会在每个 razor 部分注入代码,而不仅仅是每个模板一次(例如每次使用 HTML.TextBoxFor 时)
  2. 覆盖 ExecutePageHierarchy 方法(如上面链接的帖子中所述)。每次遇到第一个 PopContext 调用时都会引发错误:The "RenderBody" method has not been called for layout page "~/Views/Shared/_Layout.cshtml".

【问题讨论】:

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


    【解决方案1】:

    在尝试了您的解决方案后,我在呈现带有部分视图的复杂页面的 HTML 时遇到了一些问题。

    我的问题是一切都颠倒了。 (部分视图的顺序)

    纠正 - 我最终替换了 OutputStack 中的输出流

        public override void ExecutePageHierarchy()
        {
    
            // Replace output stream with a fake local stream
            StringWriter fakeOutput = new StringWriter();
    
            // Save output stack top level stream, and replace with fake local stream
            TextWriter outputStackTopOutput = OutputStack.Pop();
            OutputStack.Push(fakeOutput);
    
            // Run Razor view engine
            base.ExecutePageHierarchy();
    
            string content = fakeOutput.ToString();
            // Set back real outputs, and write to the real output 
            OutputStack.Pop();
            OutputStack.Push(outputStackTopOutput);
            outputStackTopOutput.Write(content);
        }
    

    【讨论】:

      【解决方案2】:

      现在我想我有答案了:

      public abstract class CustomWebViewPage: WebViewPage
      {
          public override void ExecutePageHierarchy()
          {
              var layoutReferenceMarkup = @"<script type=""text/html"" data-layout-id=""" + TemplateInfo.VirtualPath + @"""></script>";
      
              base.ExecutePageHierarchy();
              string output = Output.ToString();
      
              //if the body tag is present the script tag should be injected into it, otherwise simply append
              if (output.Contains("</body>"))
              {
                  Response.Clear();
                  Response.Write(output.Replace("</body>", layoutReferenceMarkup+"</body>"));
                  Response.End();
              }
              else
              {
                  Output.Write(layoutReferenceMarkup);
              }
          }
      }
      
      public abstract class CustomWebViewPage<TModel>: CustomWebViewPage
      {
      }
      

      似乎可行,但如果有人有更好的解决方案,请分享。

      【讨论】:

        猜你喜欢
        • 2017-04-16
        • 1970-01-01
        • 2013-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2016-04-04
        相关资源
        最近更新 更多