Representación de objetos C # a Html

Tenemos un montón de Entidades de Dominio que deben ser renderizadas a un formato html, que muestra sus detalles en una ventana emergente.

Me alegraría hacer algo como esto:

Product product = new Product(...); product.ToHtml(); // or: HtmlRenderer.Render(Product); 

pero mi principal problema es cómo hacer esto desde atrás. Tengo 3 respuestas diferentes:

1. Render por código:

Simplemente puedo escribir mi código para procesar el Html dentro del Método ToHtml (C #) – el problema es que es demasiado estático. si desea mover un poco el encabezado hacia el centro, debe cambiar el código. además, es muy difícil leer sangría Html en C #.

2. Usando XSL:

Los archivos XSL pueden administrar fácilmente la plantilla Html y con XSLT puedo transformar el archivo XML en el lugar correcto de los documentos. el analizador ya escrito por otra persona (solo necesita aprender la syntax) ** para esto necesitaremos que cada objeto se pueda serializar a Xml. y si el objeto cambió -> se cambiará el Xml -> el xslt también se debe cambiar ** esto también me dará la opción de aplicar sangrado al html fácilmente, por ejemplo: agregar capacidades CSS y / o cambiar el diseño html

3. usando otro motor de plantilla:

Escribir mi propio motor de plantilla C # -> Html para que lea la plantilla del archivo (* .template) e inserte la propiedad correcta en el lugar correcto de la plantilla mediante el reflection. ** en esta solución tenemos muchos problemas que podemos pensar, por ejemplo: ¿cómo debería ser la syntax? ¿esto está bien? % Nombre%% Descripción% y cómo podemos manejar matrices? ** tal vez podamos usar un motor existente (Brail o T4-Templating)?

¿Qué prefieres? conoces un buen motor? por ahora prefiero la segunda solución, pero va a ser muy lenta.

Gracias

No puedo estar más de acuerdo con John Feminella. Integrar la representación Html directamente en las entidades de su dominio es una contaminación horrible de su dominio con una preocupación completamente arbitraria y externa. Como dijo John, hará que sus entidades sean muy frágiles al hacer eso, y romperá ambas reglas críticas: separación de preocupaciones y responsabilidad única.

De las elecciones que dio, el # 3 es el más cercano a una forma apropiada de hacerlo. No necesita escribir su propio motor de plantillas. Hay muchos motores de plantillas libres y listos para usar en la red que harán el trabajo de manera más que adecuada (NVelocity, StringTemplate, Brail, etc., etc.)

Mantenga el renderizado en su lugar … en su presentación / vista, y no contamine su dominio con preocupaciones de mayor nivel.

Una vez tuve la necesidad de presentar una colección de cualquier tipo en una tabla Html. Creé un método de extensión en IEnumerable que tenía sobrecargas para css y similares. Puedes ver la publicación de mi blog aquí:

http://crazorsharp.blogspot.com/2009/03/cool-ienumberable-extension-method_25.html

Utiliza la reflexión para obtener todas las propiedades del objeto y representa una pequeña mesa bonita. Ve si eso funcionaría para ti.

 [System.Runtime.CompilerServices.Extension()] public string ToHtmlTable(IEnumerable list, string propertiesToIncludeAsColumns = "") { return ToHtmlTable(list, string.Empty, string.Empty, string.Empty, string.Empty, propertiesToIncludeAsColumns); } [System.Runtime.CompilerServices.Extension()] public string ToHtmlTable(IEnumerable list, string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle, string propertiesToIncludeAsColumns = "") { dynamic result = new StringBuilder(); if (String.IsNullOrEmpty(tableSyle)) { result.Append(""); } else { result.Append((Convert.ToString("
"); } dynamic propertyArray = typeof(T).GetProperties(); foreach (object prop in propertyArray) { if (string.IsNullOrEmpty(propertiesToIncludeAsColumns) || propertiesToIncludeAsColumns.Contains(prop.Name + ",")) { if (String.IsNullOrEmpty(headerStyle)) { result.AppendFormat("", prop.Name); } else { result.AppendFormat("", headerStyle, prop.Name); } } } for (int i = 0; i < = list.Count() - 1; i++) { if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle)) { result.AppendFormat("", i % 2 == 0 ? rowStyle : alternateRowStyle); } else { result.AppendFormat(""); } foreach (object prop in propertyArray) { if (string.IsNullOrEmpty(propertiesToIncludeAsColumns) || propertiesToIncludeAsColumns.Contains(prop.Name + ",")) { object value = prop.GetValue(list.ElementAt(i), null); result.AppendFormat("", value ?? String.Empty); } } result.AppendLine(""); } result.Append("
{0}{1}
{0}
"); return result.ToString(); }

Este es el trabajo de su vista, no sus controladores o modelos. Como sospecha, el uso del método (1) hará que sus cambios sean muy frágiles. En su lugar, escriba un fragmento de vista para cada forma en que desea representar una entidad de dominio particular. Luego, simplemente ingrese las vistas apropiadas para construir su página final.

Sinceramente prefiero el método A. El HTML ya es un estándar, por lo que no debes darte demasiadas vueltas con formatos intermedios como XML (a través de XSL – método 2) o un formato personalizado (método 3).

Si escribe en / para ASP.NET MVC, podría construir un .ASCX (control de usuario) que acepte un objeto de su tipo y represente el HTML apropiado. Y no obtienes la desagradable mella C # y no resaltas ni autocompletas.

También podría escribir múltiples vistas de usuario para acomodar diferentes escenarios para un tipo de objeto.

Después de investigar un poco, hice mi propia función para convertir Any Object toHtmlString.

VB .Net Code:

  Public Function ToHtmlString(ByVal fObj As Object) As String Dim pType = fObj.GetType() Dim props As IList(Of PropertyInfo) = pType.GetProperties() Dim value As Object = Nothing Dim htmlString As String = "
" For Each p In props value = p.GetValue(fObj, Nothing) If value <> Nothing Then htmlString += String.Format("", p.Name, value) End If Next htmlString += "
" Return htmlString.ToString()

obtendrá el nombre y el valor de la propiedad de un objeto en particular. puede manipular html en función de su

Personalmente, combinaría el método dos y tres: simplemente cree un documento XML genérico utilizando la reflexión, por ejemplo:

   ...  

y use una hoja de estilos XSTL para crear el HTML real a partir de esto.

¿Hay alguna razón por la que no desee crear un archivo .ascx de control personalizado que tome objetos de entidades de dominio como argumento y luego pueda crear la GUI como desee? De esta forma, puede agregar dinámicamente los controles a la página y simplemente establecer una propiedad para rellenarlos.

Edición 1: Simplemente represente el control en HTMLTextWriter en lugar de colocarlo en la página.

  StringBuilder outString = new StringBuilder(); StringWriter outWriter = new StringWriter(outString); HtmlTextWriter htmlText = new HtmlTextWriter(outWriter); System.Web.UI.WebControls.Label lbl1 = new System.Web.UI.WebControls.Label(); lbl1.Text = "This is just a test!"; lbl1.ToolTip = "Really"; lbl1.RenderControl(htmlText); ViewData["Output"] = outString.ToString(); 

Salida

 This is just a test! 

Por supuesto, use su control personalizado en lugar de un control integrado, pero esta fue una demostración rápida y fácil.