2017-11-16 9 views
0

私はASP.NETコアでかなり初心者です。 私は古いプロジェクトをASP.NETコアに移行しようとしています。 定義済みのレイアウトの場所で中央でレンダリングされる部分の内部に、多くのスクリプトブロックを使用します。 hereのように、使い捨てパターンのHtmlHelperを使用します。問題は、ASP.NETのコアで新しいアーキテクチャのコンテンツをキャッチするasp.netコアでどのように内部コンテンツをキャッチするためのIDisposableパターンを持つHtmlHelper拡張子

webPageBase.OutputStack.Pop() 

を使用することはできないということです。私はTagHelpers と同様の解決策を見つけましたが、私はまだHtmlHelper拡張機能を利用して、スクリプトのロジックとレンダリングを一箇所に集めておくことにします。それ以外の場合は、2つのタグヘルパーを作成し、それらを調整し、HtmlHelper拡張のすべての50〜100円をタグヘルパーに置き換える必要があります。

+0

@using (Html.BeginScripts()) { <script>console.log('foo');</script> <script>console.log('bar');</script> } @using (Html.BeginScripts()) { <script>console.log('baz');</script> } 

そしてすべてをレンダリングしますスクリプトのセクション(https://docs.microsoft.com/en-us/aspnet/core/mvc/views/layout#specifying-a-layout)を参照してください。 – CalC

+0

はい。セクションの階層レベルの異なる部分では機能しません。 –

答えて

1

HTMLヘルパーは、まだASP.NETコアのものです。タグヘルパーは、カスタムHTMLをレンダリングするための新しく一般的にはより柔軟なソリューションであるという理由だけで、HTMLヘルパーがなくなったことや、残っていることがないというわけではありません。組み込みのタグヘルパーは、実際にはHTMLヘルパーに基づいており、同じ内部バックエンドを使用して出力を生成します。だから、それは同じもののためのちょうど異なるインターフェースです。

ASP.NET Coreがビューをレンダリングする方法のために、usingブロック内のコンテンツをキャプチャすることは、タグヘルパーで動作する方法(これは非常に一般的な機能です)と比べて少し難しいです。

私はこれでしばらくの間座っていて、次のことを考え出しました。これは、ブロックが開いている限り、ビューライターを一時的にStringWriterに置き換えることによって機能します。 これは非常に恐ろしいアイデアかもしれないことに注意してください。しかし、それは...

public static class ScriptHtmlHelper 
{ 
    private const string ScriptsKey = "__ScriptHtmlHelper_Scripts"; 

    public static ScriptBlock BeginScripts(this IHtmlHelper helper) 
    { 
     return new ScriptBlock(helper.ViewContext); 
    } 

    public static IHtmlContent PageScripts(this IHtmlHelper helper) 
    { 
     if (helper.ViewContext.HttpContext.Items.TryGetValue(ScriptsKey, out var scriptsData) && scriptsData is List<object> scripts) 
      return new HtmlContentBuilder(scripts); 
     return HtmlString.Empty; 
    } 

    public class ScriptBlock : IDisposable 
    { 
     private ViewContext _viewContext; 
     private TextWriter _originalWriter; 
     private StringWriter _scriptWriter; 
     private bool _disposed; 

     public ScriptBlock(ViewContext viewContext) 
     { 
      _viewContext = viewContext; 
      _originalWriter = viewContext.Writer; 

      // replace writer 
      viewContext.Writer = _scriptWriter = new StringWriter(); 
     } 

     public void Dispose() 
     { 
      if (_disposed) 
       return; 

      try 
      { 
       List<object> scripts = null; 
       if (_viewContext.HttpContext.Items.TryGetValue(ScriptsKey, out var scriptsData)) 
        scripts = scriptsData as List<object>; 
       if (scripts == null) 
        _viewContext.HttpContext.Items[ScriptsKey] = scripts = new List<object>(); 

       scripts.Add(new HtmlString(_scriptWriter.ToString())); 
      } 
      finally 
      { 
       // restore the original writer 
       _viewContext.Writer = _originalWriter; 
       _disposed = true; 
      } 
     } 
    } 
} 

使い方は次のようになります動作します:あなたは[かみそりを使用していない理由がある

@Html.PageScripts() 
関連する問題