public static string HtmlList(IEnumerable items, HtmlDumpOptions options) { if (options == null) { options = new HtmlDumpOptions(); } if (items is IDictionary <string, object> single) { items = new[] { single } } ; var depth = options.Depth; var childDepth = options.ChildDepth; options.Depth += 1; try { var parentClass = options.ClassName; var childClass = options.ChildClass; var className = ((depth < childDepth ? parentClass : childClass ?? parentClass) ?? options.Defaults.GetDefaultTableClassName()); var headerStyle = options.HeaderStyle; var headerTag = options.HeaderTag ?? "th"; var sbHeader = StringBuilderCache.Allocate(); var sbRows = StringBuilderCacheAlt.Allocate(); List <string> keys = null; foreach (var item in items) { if (item is IDictionary <string, object> d) { if (keys == null) { keys = options.Headers?.ToList() ?? EnumerableExtensions.AllKeysWithDefaultValues(items); sbHeader.Append("<tr>"); foreach (var key in keys) { sbHeader.Append('<').Append(headerTag).Append('>'); sbHeader.Append(ViewUtils.StyleText(key, headerStyle)?.HtmlEncode()); sbHeader.Append("</").Append(headerTag).Append('>'); } sbHeader.Append("</tr>"); } sbRows.Append("<tr>"); foreach (var key in keys) { var value = d[key]; if (ReferenceEquals(value, items)) { break; // Prevent cyclical deps like 'it' binding } sbRows.Append("<td>"); if (!isComplexType(value)) { sbRows.Append(GetScalarHtml(value, options.Defaults)); } else { var htmlValue = HtmlDump(value, options); sbRows.Append(htmlValue.AsString()); } sbRows.Append("</td>"); } sbRows.Append("</tr>"); } } var isEmpty = sbRows.Length == 0; if (isEmpty && options.CaptionIfEmpty == null) { return(string.Empty); } var htmlHeaders = StringBuilderCache.ReturnAndFree(sbHeader); var htmlRows = StringBuilderCacheAlt.ReturnAndFree(sbRows); var sb = StringBuilderCache.Allocate(); sb.Append("<table"); if (options.Id != null) { sb.Append(" id=\"").Append(options.Id).Append("\""); } if (!string.IsNullOrEmpty(className)) { sb.Append(" class=\"").Append(className).Append("\""); } sb.Append(">"); var caption = options.Caption; if (isEmpty) { caption = options.CaptionIfEmpty; } if (caption != null && !options.HasCaption) { sb.Append("<caption>").Append(caption.HtmlEncode()).Append("</caption>"); options.HasCaption = true; } if (htmlHeaders.Length > 0) { sb.Append("<thead>").Append(htmlHeaders).Append("</thead>"); } if (htmlRows.Length > 0) { sb.Append("<tbody>").Append(htmlRows).Append("</tbody>"); } sb.Append("</table>"); var html = StringBuilderCache.ReturnAndFree(sb); return(html); } finally { options.Depth = depth; } }
public IRawString htmlDump(object target, Dictionary <string, object> options) => HtmlDump(target, HtmlDumpOptions.Parse(options, Context.DefaultMethods)).ToRawString();
public static HtmlString HtmlDump(this IHtmlHelper html, object target, HtmlDumpOptions options) => ViewUtils.HtmlDump(target, options).ToHtmlString();
public static string HtmlDump(object target, HtmlDumpOptions options) { if (options == null) { options = new HtmlDumpOptions(); } var depth = options.Depth; var childDepth = options.ChildDepth; options.Depth += 1; try { target = DefaultScripts.ConvertDumpType(target); if (!isComplexType(target)) { return(GetScalarHtml(target, options.Defaults)); } var parentClass = options.ClassName; var childClass = options.ChildClass; var className = ((depth < childDepth ? parentClass : childClass ?? parentClass) ?? options.Defaults.GetDefaultTableClassName()); var headerStyle = options.HeaderStyle; var headerTag = options.HeaderTag ?? "th"; if (target is IEnumerable e) { var objs = e.Map(x => x); var isEmpty = objs.Count == 0; if (isEmpty && options.CaptionIfEmpty == null) { return(string.Empty); } var first = !isEmpty ? objs[0] : null; if (first is IDictionary && objs.Count > 1 && options.Display != "table") { return(HtmlList(objs, options)); } var sb = StringBuilderCacheAlt.Allocate(); sb.Append("<table"); if (options.Id != null) { sb.Append(" id=\"").Append(options.Id).Append("\""); } if (!string.IsNullOrEmpty(className)) { sb.Append(" class=\"").Append(className).Append("\""); } sb.Append(">"); var caption = options.Caption; if (isEmpty) { caption = options.CaptionIfEmpty; } var holdCaption = options.HasCaption; if (caption != null && !options.HasCaption) { sb.Append("<caption>").Append(caption.HtmlEncode()).Append("</caption>"); options.HasCaption = true; } if (!isEmpty) { sb.Append("<tbody>"); if (first is KeyValuePair <string, object> ) { foreach (var o in objs) { if (o is KeyValuePair <string, object> kvp) { if (kvp.Value == target) { break; // Prevent cyclical deps like 'it' binding } sb.Append("<tr>"); sb.Append('<').Append(headerTag).Append('>'); sb.Append(ViewUtils.StyleText(kvp.Key, headerStyle)?.HtmlEncode()); sb.Append("</").Append(headerTag).Append('>'); sb.Append("<td>"); if (!isComplexType(kvp.Value)) { sb.Append(GetScalarHtml(kvp.Value, options.Defaults)); } else { var body = HtmlDump(kvp.Value, options); sb.Append(body.AsString()); } sb.Append("</td>"); sb.Append("</tr>"); } } } else if (!isComplexType(first)) { foreach (var o in objs) { sb.Append("<tr>"); sb.Append("<td>"); sb.Append(GetScalarHtml(o, options.Defaults)); sb.Append("</td>"); sb.Append("</tr>"); } } else { if (objs.Count > 1 || options.Display == "table") { var rows = objs.Map(x => x.ToObjectDictionary()); StringBuilderCache.Free(sb); options.HasCaption = holdCaption; return(HtmlList(rows, options)); } else { foreach (var o in objs) { sb.Append("<tr>"); if (!isComplexType(o)) { sb.Append("<td>"); sb.Append(GetScalarHtml(o, options.Defaults)); sb.Append("</td>"); } else { sb.Append("<td>"); var body = HtmlDump(o, options); sb.Append(body.AsString()); sb.Append("</td>"); } sb.Append("</tr>"); } } } sb.Append("</tbody>"); } sb.Append("</table>"); var html = StringBuilderCacheAlt.ReturnAndFree(sb); return(html); } return(HtmlDump(target.ToObjectDictionary(), options)); } finally { options.Depth = depth; } }
/// <summary> /// Recursively prints the contents of any POCO object to HTML /// </summary> public static string htmlDump(object target, HtmlDumpOptions options) => HtmlScripts.HtmlDump(target, options);