LinqPad有个非常强大的Dump函数。这篇讲解一下如何将Dump函数应用在.Net MVC Web开发中。
先看效果:
经过反编译发现,Dump函数调用了LINQPad.ObjectGraph.Formatters.XhtmlWriter类中FormatObject函数,把对象转成了Html。

由于FormatObject函数是protect类型,不能直接调用,只能反射了。

BigDump.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Reflection; using System.IO; using System.Text; namespace System.Web { public static class BigDump { private static MethodInfo dumpMethodInfo = null; private static object xhtmlWriterInstance = null; private static void Init() { if (dumpMethodInfo == null || xhtmlWriterInstance == null) { var asm = Assembly.LoadFile(HttpContext.Current.Server.MapPath("~/Lib/LINQPad.exe")); Type t1 = asm.GetType("LINQPad.ObjectGraph.Formatters.XhtmlWriter"); ConstructorInfo t1Constructor = t1.GetConstructor(new Type[] { typeof(TextWriter), typeof(bool) }); xhtmlWriterInstance = t1Constructor.Invoke(new Object[] { new StringWriter(new StringBuilder()), false }); dumpMethodInfo = t1.GetMethod("FormatObject", BindingFlags.Instance | BindingFlags.NonPublic); } } public static MvcHtmlString Render<T>(this T o, string description = "", int? depth = 3) { Init(); var result = dumpMethodInfo.Invoke(xhtmlWriterInstance, new Object[] { o, description, depth, new TimeSpan() }); return new MvcHtmlString(result as string); } public static List<MvcHtmlString> Stack { get; set; } static BigDump() { Stack = new List<MvcHtmlString>(); } public static T Dump<T>(this T o, string description = "", int? depth = 3) { Stack.Add(o.Render(description, depth)); return o; } public static void Clear() { Stack = new List<MvcHtmlString>(); } public static MvcHtmlString Flush() { var html = new MvcHtmlString(string.Join("\r\n", Stack.Select(r => r.ToHtmlString()).ToArray())); Clear(); return html; } } }
linqpad.css
body {
margin: 0.3em 0.3em 0.4em 0.5em;
font-family: Verdana;
font-size: 50%;
background: white;
}
p, pre {
margin: 0;
padding: 0;
font-family: Verdana;
}
table {
border-collapse: collapse;
border: 2px solid #17b;
border-top: 1px;
margin: 0.3em 0.2em;
}
table.limit {
border-collapse: collapse;
border-bottom: 2px solid #c31;
}
td, th {
vertical-align: top;
border: 1px solid #aaa;
padding: 0.1em 0.2em;
margin: 0;
}
th {
text-align: left;
background-color: #ddd;
border: 1px solid #777;
font-family: tahoma;
font-size: 90%;
font-weight: bold;
}
th.member {
padding: 0.1em 0.2em 0.1em 0.2em;
}
td.typeheader {
font-family: tahoma;
font-size: 100%;
font-weight: bold;
background-color: #17b;
color: white;
padding: 0 0.2em 0 0.1em;
}
td.n {
text-align: right;
}
a:link.typeheader, a:visited.typeheader {
font-family: tahoma;
font-size: 90%;
font-weight: bold;
text-decoration: none;
background-color: #17b;
color: white;
float: left;
}
span.typeglyph {
font-family: webdings;
padding: 0 0.2em 0 0;
margin: 0;
}
table.group {
border: none;
margin: 0;
}
td.group {
border: none;
padding: 0 0.1em;
}
div.spacer {
margin: 0.6em 0;
}
table.headingpresenter {
border: none;
border-left: 3px dotted #1a5;
margin: 1em 0em 1.2em 0.15em;
}
th.headingpresenter {
font-family: Arial;
border: none;
padding: 0 0 0.2em 0.5em;
background-color: white;
color: green;
font-size: 110%;
}
td.headingpresenter {
border: none;
padding: 0 0 0 0.6em;
}
td.summary {
background-color: #def;
color: #024;
font-family: Tahoma;
padding: 0 0.1em 0.1em 0.1em;
}
td.columntotal {
font-family: Tahoma;
background-color: #eee;
font-weight: bold;
color: #17b;
font-size: 90%;
text-align: right;
}
span.graphbar {
background: #17b;
color: #17b;
margin-left: -2px;
margin-right: -2px;
}
a:link.graphcolumn, a:visited.graphcolumn {
color: #17b;
text-decoration: none;
font-weight: bold;
font-family: Arial;
font-size: 110%;
letter-spacing: -0.4em;
margin-left: 0.3em;
}
i {
color: green;
}
em {
color: red;
}
span.highlight {
background: #ff8;
}