Blog de Oxxigeno


Buenas pr谩cticas: aspx sin c贸digo de servidor

Escrito por Israel Vi帽uales en .NET, Desarrollo

La capa de presentaci贸n de un sitio web es una parte muy sensible del mismo, pues debe proporcionar al usuario toda la informaci贸n que solicita, de forma que la carga de proceso en la misma sea m铆nima.

Los sitios web desarrollados bajo el .NET framework son publicados con una precompilaci贸n del c贸digo fuente, sin embargo, las p谩ginas aspx y los controles ascx son interpretados en tiempo de ejecuci贸n. Es decir: cada vez que un usuario solicita una p谩gina aspx 茅sta es interpretada por el servidor de aplicaciones y presentada al cliente.

Como puede suponerse, el hecho de que la p谩gina aspx contenga c贸digo fuente que deba ser compilado ralentizar谩 la carga de la misma, puesto que se pasa de interpretar html y devolverlo a compilar c贸digo de servidor con m谩s o menos l贸gica.

En muchas ocasiones es posible pensar que no nos es posible crear la p谩gina aspx tal y como queremos sin incluir c贸digo de servidor en la misma, esto es un error muy com煤n, pero facilmente subsanable, siguiendo las siguientes recomendaciones.

  • Solo est谩 permitido utilizar c贸digo de servidor para cargar elementos dentro de controles de tipo DataBound (GridView, FormView, etc.). Aun as铆 es poco recomendable porque sigue requiriendo compilaci贸n. Se recomienda la utilizaci贸n del control Repeater.
 
                <%# Eval("TipoDePagina.Nombre") %>
 
                Editar Contenidos
  • Si necesitamos que un elemento HTML obtenga propiedades (style, href, title, etc.) desde el lado del servidor, porque utilice alguna l贸gica de negocio debemos identificar a 茅ste elemento con runat=server y asignar dichas propiedades desde el code-behind, que va precompilado cuando se publica.

aspx no recomendado:

<div id="global" class="fondo-menu-&lt;%= ambitoCabecera %&gt;">
<div id="cabecera" class="cabecera-&lt;%= ambitoCabecera%&gt;">
<div id="cabecera-logo">
            <a title="Alt" href="#">
                <img id="imgLogo" src="../images/&lt;%= image%&gt;" alt="Grupo Banco Popular" width="148" height="50" />
            </a></div>
<div id="shortcuts">
<ul class="horizontal">
	<li><a href="#">Atenci贸n al cliente</a> |</li>
	<li><a href="#">Sucursales</a> |</li>
	<li><a href="#">Tarifas</a> |</li>
	<li><a href="#">Simuladores</a></li>
</ul>
</div>
<div id="buscador">
            <fieldset>
 
            </fieldset></div>
</div>
</div>

C贸digo no recomendado:

// Imagen por omision para el logo
public string _image = "default.jpg";
// Ambito por omision para la cabecera
public string _ambitoCabecera = "normal";
 
protected void Page_Load(object sender, EventArgs e)
{
 
    #region Dar valores a las variables
    ...
    #endregion
 
}

aspx recomendado:

<div id="global">
<div id="cabecera">
<div id="cabecera-logo">
            <a title="Alt" href="#">
                <img alt="Grupo Banco Popular" width="148" height="50" />
            </a></div>
<div id="shortcuts">
<ul class="horizontal">
	<li><a href="#">Atenci贸n al cliente</a> |</li>
	<li><a href="#">Sucursales</a> |</li>
	<li><a href="#">Tarifas</a> |</li>
	<li><a href="#">Simuladores</a></li>
</ul>
</div>
<div id="buscador">
            <fieldset>
 
            </fieldset></div>
</div>
</div>

C贸digo recomendado:

protected void Page_Load(object sender, EventArgs e)
{
    // Imagen por omision para el logo
    string image = "default.jpg";
    // Ambito por omision para la cabecera
    string ambitoCabecera = "normal";
 
    #region Dar valores a las variables
    ...
    #endregion
 
    this.global.Attributes.Add("class", "fondo-menu-" + ambitoCabecera);
    this.cabecera.Attributes.Add("class", "cabecera-" + ambitoCabecera);
    this.imgLogo.Src = "../images/" + image;
 
}
  • Si necesitamos que un elemento HTML reciba su identificador, propiedades sensibles o una maquetaci贸n compleja dependiente de una l贸gica de negocio, la soluci贸n optima es crear un custom web control para definirlo, 茅ste tipo de controles heredan de la clase WebControl.
namespace Example.Web.UI.Controls
{
    [DefaultProperty("Text"), ToolboxData("&lt;{0}:OnlyText runat=server&gt;<!--{0}:OnlyText-->")]
    public class OnlyText : System.Web.UI.WebControls.WebControl
    {
        #region Attributes
 
        private string _text = "";
 
        #endregion
 
        #region Properties
 
        [Bindable("true"), Category("Data"), DefaultValue("")]
        public string Text
        {
            get { return _text;}
            set { _text = value;}
        }
 
        #endregion
 
        #region Overrides Methods
 
        protected override void  Render(HtmlTextWriter writer)
        {
             writer.Write(Text);
        }
 
        #endregion
    }
}

3 comentarios

  1. Modesto San Juan dijo el 18/02/2009:

    Las p谩ginas .aspx y los controles .ascx son compilados en la primera request (si es que no se ha hecho una precompilaci贸n previa) y en posteriores peticiones se recurre a la clase compilada tanto si se ha utilizado c贸digo de servidor como si no se ha utilizado. Existen determinadas circunstancias que llevan al servidor a recompilar estas p谩ginas o controles (cambios en el fichero, configuraci贸n, etc.) pero de ning煤n modo es correcto decir que el c贸digo de servidor que hay dentro de una p谩gina .aspx sea c贸digo interpretado.

    En base al contenido del fichero .aspx se genera un fichero de c贸digo que se compila y se ejecuta. El resultado de esta operaci贸n puede ser consultado en la carpeta “Temporary ASP.NET Files”.

    Es cierto que la inclusi贸n se c贸digo de servidor dentro de los ficheros .aspx en lugar de recurrir a la clase trasera de la p谩gina (.aspx.cs) se ha considerado una mala praxis desde la aparici贸n del modelo de Web Forms propuesto por Microsoft en ASP.Net. Aunque desde un punto de vista purista, todo aquello que est茅 entre “” se considera c贸digo de servidor, independientemente de si se trata de un contexto de databinding o no.

    El principal objetivo de esta regla es b谩sicamente separar las capas de l贸gica de negocio de la presentaci贸n, algo que desde la aparici贸n de ASP.Net MVC se puede enfocar desde otra manera. Sin posicionarme ni a favor ni en contra de ninguno de los dos modelo (ASP.Net MVC vs Web Forms), resulta curioso c贸mo lo que en un modelo se considera una mala praxis, en el otro es una pr谩ctica habitual debido a que establece otros mecanismos de separaci贸n de la l贸gica de negocio y la presentaci贸n.

  2. ivinuales dijo el 18/02/2009:

    Buenas tardes,

    Ciertamente el termino “interpretado” no ha sido el m谩s acertado jeje.

    Es cierto que aspnet realiza un compilado de las p谩ginas la primera vez que se realiza una petici贸n, quedando una clase compilada del estilo default.aspx.cdcab7d2.compiled.

    Sin embargo, en ciertos casos, nuestra experiencia nos dice que esto no es recomendable, por ejemplo, para portales con un gran n煤mero de p谩ginas y controles (se generan y cargan un gran numero de dlls y el rendimiento cae), o en portales con alto ratio de actualizaci贸n en las paginas y controles; en estos casos hemos comprobado que forzar la no compilaci贸n del aspx favorece el rendimiento, pero si el aspx no esta compilado el rendimiento se ve afectado si tienes c贸digo de servidor en la p谩gina o control.

    As铆 pues hemos optado por adoptar como buena pr谩ctica reducir al m谩ximo el c贸digo de servidor dentro de las p谩ginas y controles.

    Aunque es cierto que el objetivo fundamental de no utilizar c贸digo de servidor en p谩ginas o controles es la separaci贸n l贸gica/presentaci贸n.

    Respecto a MVC Framework, prometo ponerme al d铆a sobre 茅l en cuanto tenga un ratejo de relax.

    Y abro un thread de discusi贸n sobre el y comentamos sus bondades y maldades jejeje.

    Un saludo!

  3. Modesto San Juan dijo el 19/02/2009:

    Hola Israel,

    No puedo estar m谩s de acuerdo! No obstante, cuando se dan esos escenarios y tenemos que lidiar con portales sometidos a un alto n煤mero de visitas o con altos ratios de actualizaci贸n, es altamente recomendable recurrir a la ayuda de herramientas especializadas que proporcionen los mecanismos de cach茅, publicaci贸n, actualizaci贸n del portal, etc. adecuados al rendimiento requerido por el cliente y sus usuarios.

    Un saludo!

Deja un comentario


Nuestras oficinas:

Oxxigeno Espa帽a
C/Luchana, 23. 28010 - Madrid
Tel.: 91 144 12 00
Fax: 91 144 12 01
E-mail:

Oxxigeno France
77, rue La Bo毛tie. 75008 - Paris
Tel.: +33 (0)1 45 61 68 99
Fax: +33 (0)1 45 61 51 05
E-mail: