public void WriteObject(object objectToWrite) { var objectRecord = new ObjectRecord(objectToWrite); var recordService = new ObjectRecordService(objectToWrite, null); var formService = new ObjectFormService(objectToWrite, recordService); var formMetadata = formService.GetFormMetadata(objectToWrite.GetType().AssemblyQualifiedName); foreach (var section in formMetadata.FormSections.OrderBy(s => s.Order)) { if (section is FormFieldSection fieldSection) { if (fieldSection.FormFields.Any(f => objectToWrite.IsInContext(f.FieldName))) { _content.AppendLine("<p>"); if (fieldSection.DisplayLabel) { AppendSectionHeading(fieldSection.SectionLabel); } foreach (var field in fieldSection.FormFields.OrderBy(f => f.Order)) { if (objectToWrite.IsInContext(field.FieldName)) { if (field.DisplayLabel) { AppendFieldHeading(recordService.GetFieldLabel(field.FieldName, objectRecord.Type)); } if (recordService.GetFieldType(field.FieldName, objectRecord.Type) == RecordFieldType.Enumerable) { //okay need to generate a table var enumerableMetadata = recordService.GetFieldMetadata(field.FieldName, objectRecord.Type) as EnumerableFieldMetadata; var gridFieldMetadata = recordService.GetGridFields(enumerableMetadata.EnumeratedTypeQualifiedName, ViewType.AssociatedView); var table = new StringBuilder(); table.AppendLine("<table>"); table.AppendLine("<thead><tr>"); var fieldJustifies = new Dictionary <string, string>(); foreach (var gridField in gridFieldMetadata) { var justify = recordService.GetFieldType(gridField.FieldName, enumerableMetadata.EnumeratedTypeQualifiedName).GetHorizontalJustify(true); var htmlJustify = justify == HorizontalJustify.Left ? "left" : justify == HorizontalJustify.Middle ? "center" : "right"; fieldJustifies.Add(gridField.FieldName, htmlJustify); } foreach (var gridField in gridFieldMetadata) { table.AppendLine($"<th width={gridField.WidthPart} {thStyle.Replace("left", fieldJustifies[gridField.FieldName])}>{recordService.GetFieldLabel(gridField.FieldName, enumerableMetadata.EnumeratedTypeQualifiedName)}</th>"); } table.AppendLine("</tr></thead>"); var linkedObjects = recordService .GetLinkedRecords(enumerableMetadata.EnumeratedTypeQualifiedName, objectRecord.Type, field.FieldName, objectRecord.Id) .Cast <ObjectRecord>() .ToArray(); var objectsForTable = linkedObjects .Take(MaximumNumberOfEntitiesToList) .ToArray(); foreach (var gridRecord in objectsForTable.Take(MaximumNumberOfEntitiesToList)) { table.AppendLine("<tr>"); foreach (var gridField in gridFieldMetadata .Where(gf => objectsForTable.Any(o => o.Instance.IsInContext(gf.FieldName)))) { table.AppendLine(string.Format("<td {0}>", tdStyle.Replace("left", fieldJustifies[gridField.FieldName]))); table.Append(recordService.GetFieldAsDisplayString(gridRecord, gridField.FieldName)); table.AppendLine("</td>"); } table.AppendLine("</tr>"); } table.AppendLine("</table>"); _content.AppendLine(table.ToString()); if (linkedObjects.Count() > MaximumNumberOfEntitiesToList) { AppendParagraph(string.Format("Note this list is incomplete as the maximum of {0} items has been listed", MaximumNumberOfEntitiesToList)); } } else { AppendFieldValue(recordService.GetFieldAsDisplayString(objectRecord, field.FieldName)); } } } _content.AppendLine("</p>"); } } } }