2011-03-10 22 views
8

Cuando genero mis controles en ASP.net que salen como esto:ASP.net render HTML muy bien (Embellecer)

<div id="ctl00_mainContent_ApprovalSelectPanel" class="discussWrapper"> 

     <span class="cbox highlighted"><input id="ctl00_mainContent_ctl00" type="checkbox" name="ctl00$mainContent$ctl00" checked="checked" value="70" /><label for="ctl00_mainContent_ctl00">Buyer1</label></span><span class="cbox"><input id="ctl00_mainContent_ctl01" type="checkbox" name="ctl00$mainContent$ctl01" value="75" /><label for="ctl00_mainContent_ctl01">Buyer2</label></span><span class="cbox"><input id="ctl00_mainContent_ctl02" type="checkbox" name="ctl00$mainContent$ctl02" value="280" /><label for="ctl00_mainContent_ctl02">Client3</label></span><span class="cbox"><input id="ctl00_mainContent_ctl03" type="checkbox" name="ctl00$mainContent$ctl03" value="281" /><label for="ctl00_mainContent_ctl03">Client4</label></span><span class="cbox"><input id="ctl00_mainContent_ctl04" type="checkbox" name="ctl00$mainContent$ctl04" value="283" /><label for="ctl00_mainContent_ctl04">Client2</label></span><span class="cbox"><input id="ctl00_mainContent_ctl05" type="checkbox" name="ctl00$mainContent$ctl05" value="289" /><label for="ctl00_mainContent_ctl05">Client1</label></span><span class="cbox"><input id="ctl00_mainContent_ctl06" type="checkbox" name="ctl00$mainContent$ctl06" value="346" /><label for="ctl00_mainContent_ctl06">artworker1</label></span><span class="cbox"><input id="ctl00_mainContent_ctl07" type="checkbox" name="ctl00$mainContent$ctl07" value="362" /><label for="ctl00_mainContent_ctl07">buyer3</label></span><span class="cbox"><input id="ctl00_mainContent_ctl08" type="checkbox" name="ctl00$mainContent$ctl08" value="367" /><label for="ctl00_mainContent_ctl08">meeeee</label></span><span class="cbox"><input id="ctl00_mainContent_ctl09" type="checkbox" name="ctl00$mainContent$ctl09" value="368" /><label for="ctl00_mainContent_ctl09">stake</label></span> 

    </div> 

bastante feo y difícil de entender cuando se ve la fuente. Normalmente, este no es un problema, pero mi sitio ofrece recursos y tutoriales para visitantes, donde está en la fuente.

¿Hay alguna forma de representar estos controles correctamente? ¿Sangrado apropiadamente, mejores identificaciones y nombres, etc.?

+4

usted no va a obtener el código fuente bonita con formularios web. Si desea utilizar ASP.NET MVC es una propuesta mucho mejor. – UpTheCreek

+0

yo personalmente considero que los nombres (siempre y "feos", tal como aparecen) son una forma muy sensible, sobre todo con la participación de los escenarios repetidores, controles anidados, plantillas y más o menos "todo no trivial"; solo use mejores selectores/clases de CSS (evite los selectores basados ​​en ID para los controles ASP.NET) y el enlace de datos (para evitar la codificación rígida del ID de cliente) y * no * trate los nombres generados como un recurso estático. –

Respuesta

14

En .NET 4.0 puede establecer ClientIDMode en una de las 4 opciones AutoID, Static, Predictable e Inherit. Probablemente esté buscando Estático ya que esto garantizará que sus controles se muestren en la página con los ID que les haya asignado.

Se puede establecer a nivel de aplicación mediante la adición:

<pages clientIDMode="Static"> 

Para su web.config

hay más detalles sobre estos cambios aquí: http://beyondrelational.com/blogs/hima/archive/2010/07/16/all-about-client-id-mode-in-asp-net-4.aspx

+0

Esto se ve muy bien para ID gracias, ¿alguna idea sobre sangrado y saltos de línea? –

+0

Esto es asombroso. ¿Esto se aplica al nombre, así como a la identificación o solo a la identificación? Esto hará que las secuencias de comandos y css sean mucho más fáciles que antes. Muchas gracias :) –

+0

Hombre, ojalá tuviera eso cuando estaba codificando aplicaciones ASP.NET 2.0. –

2

poniendo muy salida va para ser casi imposible, porque el analizador no tiene ningún concepto de contexto al realizar controles. Muchos controles representan más de un elemento HTML, y necesitarían conocer su contexto para hacer esto ... así como también saber qué tipo de formato se deseaba (por ejemplo, para controles de lista, cuándo comenzar una nueva línea, cuándo para sangrar de nuevo).

Además, no todos los elementos en el marcado se representan realmente, y el diseño de su marcado no siempre está directamente relacionado con el diseño de la salida. Por ejemplo:

<asp:PlaceHolder runat="server" /> 
    <asp:Panel runat="server" /> 
     <asp:DropDownList runat="server" /> 
    </asp:Panel /> 
</asp:PlaceHolder /> 

Placeholder no se representa, por lo que habría que hacer una sangría en la salida o no? DropDownList renderiza múltiples controles HTML, y no hay forma de que determine la forma deseada de renderizar: ¿debería sangrar al mismo nivel que el primer control? ¿Debería renderizar sin espaciado entre elementos? Desde un punto de vista práctico, es más eficiente renderizar sin espacio (que es lo que hacen la mayoría de los controles) para minimizar la cantidad de datos que se deben enviar al cliente.

Finalmente, incluso en los casos simples, la representación real cuando "visualiza la fuente" desde un navegador probablemente será diferente entre los navegadores. Todos ellos pueden optar por manejar el espaciado, los saltos de línea, la sangría de la forma que elijan, ya que el espaciado entre elementos no afecta la representación de ninguna manera.

Si muestra ejemplos de "antes/después" en su sitio web, realmente no tiene más remedio que formatear manualmente el resultado para la presentación, si esto es lo que desea. Si la gente también quiere ver la fuente, está bien, pero sería muy difícil hacer que la fuente siempre se vea tan bien como su marca.

Si esto fue realmente importante para usted, podría interceptar el flujo de salida y reformatearlo antes de enviarlo al cliente, pero no sucederá directamente desde el motor de renderizado de asp.net. Para obtener un ejemplo de cómo hacer esto, google "asp.net response filter" - here's one. Estoy seguro de que no es difícil encontrar código que formatee HTML que podría aplicar a este concepto.

6

ASP.NET WebForms HTML rendering y control markup se han mejorado en .NET 4.0 y esto ayudará con los ID de control y la estructura de los elementos HTML mismos (como se menciona en Rob Stone's answer a su pregunta). Sin embargo, las sangrías y saltos de línea aún pueden ser menos que deseables para sus necesidades.

Si el código HTML realmente es parte de la experiencia del usuario para su aplicación, es posible que que no escribe una HttpModule adjunta al evento ReleaseRequestState. Este enfoque abordará los saltos de línea e indentaciones reales de su fuente HTML. Para avoid re-inventing the wheel usted podría utilizar el .NET port of HTML Tidy o una .NET Wrapper for HTML Tidy como parte de su filtro personalizado en la respuesta.

Hay un buen ejemplo de cómo se puede escribir un filtro personalizado en un HttpModule en this blog. La sección del código que he encontrado más útil es la siguiente (con pequeñas modificaciones, pero se puede obtener la comprensión completa del blog en sí):

public class CustomModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
    context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState); 
    } 

    private void context_ReleaseRequestState(object sender, EventArgs e) 
    { 
    HttpResponse response = HttpContext.Current.Response; 
    if (string.Compare(response.ContentType,"text/html",true) == 0) 
    { 
     response.Filter = new CustomFilter(response.Filter,response.ContentEncoding); 
    } 
    } 
} 

y dentro de su clase CustomFilter ...

public override void Write(byte[] buffer, int offset, int count) 
{ 
    sb = new StringBuilder(count + 1024); 
    sb.Append(enc.GetString(buffer,offset,count)); 

    // <---- Run the sb content through HTML Tidy here ----> 

    byte[] buff = enc.GetBytes(sb.ToString()); 
    s.Write(buff,0,buff.Length); 
    } 
} 
+0

Interesante proposición; sin embargo, si a nadie más que a un desarrollador le importa cómo se ve la fuente, siempre que el HTML sea válido (para el navegador) ... entonces solo se desperdicia recursos ... por lo que este enfoque podría ser mejor solo en los modos de "desarrollo". –

+0

@pst - Estoy de acuerdo con su comentario para la mayoría de los sitios web. En este caso, aunque OP ha declarado _ "mi sitio ofrece recursos y tutoriales a los visitantes, donde mirar la fuente es parte de la experiencia" _, por lo que probablemente valga la pena los recursos adicionales desde ese punto de vista. Tiene sentido, ¿verdad? –

+1

¿Por qué * mentir * sobre la experiencia ASP.NET? ;-) –

1

Llegó tarde a la fiesta aquí, pero me enfrenté a un problema similar. Estábamos generando un javascript altamente complejo que se estaba volviendo demasiado complicado para depurarlo razonablemente, todo enredado en línea con el resto del marcado. Así que se me ocurrió esta clase. ejemplo

public class HtmlPrettyControl : HtmlGenericControl 
{ 
    public bool Indent { get; set; } 

    public HtmlPrettyControl(string tag) : this(tag, true) { } 

    public HtmlPrettyControl(string tag, bool indent) : base(tag) 
    { 
     Indent = indent; 
    } 

    protected override void Render(HtmlTextWriter writer) 
    { 
     // Here you can check if you are running against a production environment 
     // and just do base.Render to prevent extra code execution and space in 
     // your response to the client 

     if (Indent) 
     { 
      RenderBeginTag(writer); 
      writer.WriteLine(); 
      writer.Indent++; 
      base.RenderChildren(writer); 
      writer.WriteLine(); 
      writer.Indent--; 
      RenderEndTag(writer); 
     } 
     else 
     { 
      base.Render(writer); 
     } 
     writer.WriteLine(); 
    } 
} 

Uso:

var myDiv = new HtmlPrettyControl("div"); 
var myLabel = new HtmlPrettyControl("label", false); 
myLabel.InnerText = "I'm sorry, Dave."; 
myDiv.Controls.Add(myLabel) 

Genera marcado:

<div> 
    <label>I'm sorry, Dave.</label> 
<div> 

utilizamos un similares Render método de reemplazo para los controles que no son simples etiquetas HTML (en una clase base diferente/cadena de herencia). El único inconveniente es que no parece ser informado del nivel de sangría actual de un ascx que su control está viviendo en (si lo hay) del writer pasado al método Render. Por lo tanto, aunque la jerarquía del control y sus elementos secundarios está bien indentada y dividida, se restablecerán a un nivel de indentación de 0, rompiendo el flujo general del marcado surround en los archivos de diseño aspx o aspx.

+0

Argumentaría que el problema fundamental aquí es empujar en JavaScript con el marcado simple ;-) Tengo un control (en realidad dos, dependiendo del contexto) solo para facilitar la representación de JavaScript para la inclusión de marcado y código detrás de eso también se ocupa de los demás detalles; los eventos en línea también se desacoplan de manera similar con la "vinculación" a las tiendas de funciones de JavaScript administradas. –

+0

Oh, sí, nunca diría que nuestro enfoque actual (el problema que estaba tratando de resolver con esta clase) era ideal o incluso elegante. Pero esta solución particular aquí, creo, está a punto para la pregunta original. –

Cuestiones relacionadas