mardi 7 mars 2017

Capturing parts of MVC Views

I am capturing parts of MVC views like so:

<% using(Html.BeginScriptWrapper()) { %>
<script type="text/javascript">
    alert("Test : <%: DateTime.Now %>");
</script>
<% } %>

The code of HtmlHelper extension:

public static class HelperScriptWrapper
{
  public static IDisposable BeginScriptWrapper(this HtmlHelper anHtml)
  {
    return new ScriptWrapper(anHtml);
  }

  class ScriptWrapper : IDisposable
  {
    private HtmlHelper fHtml;
    private TextWriter fOldWriter;
    private StringWriter fNewWriter;

    private TextWriter ReplaceInnerWriter(TextWriter aReplacement)
    {
      TextWriter writer = fHtml.ViewContext.HttpContext.Response.Output;
      PropertyInfo propInfo = writer.GetType().GetProperty("InnerWriter",
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

      TextWriter oldWriter = propInfo.GetValue(writer, null) as TextWriter;
      propInfo.SetValue(writer, aReplacement, null);

      return oldWriter;
    }

    public ScriptWrapper(HtmlHelper anHtml)
    {
      fHtml = anHtml;
      fNewWriter = new StringWriter();
      fOldWriter = ReplaceInnerWriter(fNewWriter);
    }

    public void Dispose()
    {
      ReplaceInnerWriter(fOldWriter);
      string result = fNewWriter.GetStringBuilder().ToString();
      // store result to use later
    }
  }
}

Reflection is used to replace InnerWriter above with my StringWriter.

Is there a proper (ASP.NET MVC by-design) way to do this without reflection? That is to redirect content that goes to Response.Output in the middle of the view.

Aucun commentaire:

Enregistrer un commentaire