In my last post I talked about adding blocks to ms mvc to capture output. Our solution used an ugly hack with reflection, type caching, and lwg. Thanks to Jeremy Skinner and Phil who both pointed out you can use a response output filter to do the same thing. So here is an update to our capturing class.
/// <summary>Renders the action and returns a string.</summary>
/// <param name=”viewRenderer”>The delegate to render.</param>
/// <returns>The rendered text.</returns>
public string Capture(Action viewRenderer)
{
IHttpResponse resp = _httpContext.Response;
Stream originalFilter = null;
CapturingResponseFilter innerFilter;
string capturedHtml = ““;
if (viewRenderer != null)
{
try
{
resp.Flush();
originalFilter = resp.Filter;
innerFilter = new CapturingResponseFilter(resp.Filter);
resp.Filter = innerFilter;
viewRenderer();
resp.Flush();
capturedHtml = innerFilter.GetContents(resp.ContentEncoding);
}
finally
{
if (originalFilter != null)
{
resp.Filter = originalFilter;
}
}
}
return capturedHtml;
}
The only thing to remember is to flush current response before and after you capture the text. The CapturingResponseFilter just inherits from Stream and is using a MemoryStream internally. The call to GetContents just dumps the memory stream to a string using the current encoding of the response.
What do you think… much simpler
Thanks Jeremy and Phil.