2015-01-09 68 views
2

我試圖創建一個自定義Razor視圖基類(繼承WebViewPage),它將爲呈現的每個視圖模板(包括佈局和部分視圖)插入一點HTML,以便我在每個Razor模板開始的地方都有一個參考(對結束的地方不感興趣)。當剃刀模板呈現時自定義WebViewPage注入代碼

我至今嘗試過是

  1. 重寫Write方法(如在評論here描述)。這會在每個剃鬚刀部分注入代碼,而不僅僅是每個模板一次(例如,每次使用HTML.TextBoxFor時)。覆蓋ExecutePageHierarchy方法(如上面鏈接的文章中所述)
  2. 。這將引發錯誤每次它遇到第一個PopContext通話時間:The "RenderBody" method has not been called for layout page "~/Views/Shared/_Layout.cshtml".

回答

1

認爲我現在回答這個:

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 
{ 
} 

似乎工作,但如果任何人有一個更好的解決方案,請分享。

4

嘗試您的解決方案後,我對使用部分視圖呈現的複雜頁面的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); 
    }