Skip to content

Instantly share code, notes, and snippets.

@lars-erik
Created July 25, 2012 14:16
Show Gist options
  • Save lars-erik/3176410 to your computer and use it in GitHub Desktop.
Save lars-erik/3176410 to your computer and use it in GitHub Desktop.
ASP.NET Control Snapshot Renderer
public class ControlRenderer : IDisposable
{
public static string RenderContents(Control control)
{
using (var renderer = new ControlRenderer(control))
{
return renderer.Render();
}
}
private string Render()
{
try
{
RememberAspNetValidation();
DisableAspNetValidation();
InvokeRender();
}
finally
{
ResetAspNetValidation();
}
return RenderedContents();
}
private string RenderedContents()
{
return builder.ToString();
}
private void InvokeRender()
{
renderMethod.Invoke(control, new object[] {htmlWriter});
}
private void RememberAspNetValidation()
{
originalInOnFormRender = (bool)inOnFormRenderField.GetValue(control.Page);
originalEnableEventValidation = (bool)enableEventValidationField.GetValue(control.Page);
}
private void ResetAspNetValidation()
{
inOnFormRenderField.SetValue(control.Page, originalInOnFormRender);
enableEventValidationField.SetValue(control.Page, originalEnableEventValidation);
}
private void DisableAspNetValidation()
{
inOnFormRenderField.SetValue(control.Page, true);
enableEventValidationField.SetValue(control.Page, false);
}
private ControlRenderer(Control controlToRender)
{
control = controlToRender;
builder = new StringBuilder();
writer = new StringWriter(builder);
htmlWriter = new HtmlTextWriter(writer);
}
void IDisposable.Dispose()
{
writer.Dispose();
htmlWriter.Dispose();
}
private const BindingFlags PrivateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
private static readonly Type pageType = typeof(Page);
private static readonly Type controlType = typeof(Control);
private static readonly FieldInfo inOnFormRenderField = pageType.GetField("_inOnFormRender", PrivateInstance);
private static readonly FieldInfo enableEventValidationField = pageType.GetField("_enableEventValidation", PrivateInstance);
private static readonly MethodInfo renderMethod = controlType.GetMethod("Render", PrivateInstance);
private readonly StringBuilder builder;
private readonly StringWriter writer;
private readonly HtmlTextWriter htmlWriter;
private readonly Control control;
private bool originalInOnFormRender;
private bool originalEnableEventValidation;
}
@lars-erik
Copy link
Author

Makes it possible to render a snapshot of an ASP.NET control even if you don't render a containing Form and/or outside the main Render chain.

Just do ControlRenderer.Render(this) from anywhere, and you get a string representing the current output of this, being a Control or a Page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment