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; }