【问题标题】:Custom WebViewPage inject code when razor template is rendering渲染剃刀模板时自定义 WebViewPage 注入代码
【发布时间】:2015-01-09 12:02:54
【问题描述】:
我正在尝试创建一个自定义 Razor 视图基类(继承 WebViewPage),它将为每个正在呈现的视图模板(包括布局和部分视图)注入一些 HTML,以便我在客户端上有一个参考每个 Razor 模板的开始位置(对它的结束位置不感兴趣)。
到目前为止我尝试过的是
- 覆盖Write 方法(如评论here 中所述)。这会在每个 razor 部分注入代码,而不仅仅是每个模板一次(例如每次使用 HTML.TextBoxFor 时)
- 覆盖 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
{
}
似乎可行,但如果有人有更好的解决方案,请分享。