lunes, 4 de octubre de 2010

Sitio web o aplicación web

Diferencias entre sitio web y aplicación web

Antes de comenzar y para no llevar a engaño a nadie, copio literalmente un texto que me parece bastante determinante:

“No hay ninguna diferencia de rendimiento entre un proyecto de sitio web y un proyecto de aplicación web.”
http://msdn.microsoft.com/es-es/library/dd547590.aspx

A partir de aquí, utilizar un sitio web o una aplicación web ya es decisión nuestra en función de sus ventajas o desventajas.

Archivo > Nuevo > Sitio web…

clip_image002

Archivo > Nuevo > Proyecto…

clip_image004

La primera diferencia es donde guarda los ficheros de forma predeterminada Visual Studio 2010 según el tipo de proyecto.

·        Sitio web.

o   Carpeta para el sitio web dentro de C:\Users\<Usuario>\Documents\Visual Studio 2010\WebSites.

o   1 fichero .sln dentro de C:\Users\<Usuario>\Documents\Visual Studio 2010\Projects.

·        Aplicación web.

o   Sólo 1 carpeta que contiene tanto la aplicación como 1 fichero .sln y 1 fichero .vbproj, dentro de C:\Users\<Usuario>\Documents\Visual Studio 2010\Projects.

 

Sitio web

Aplicación web

Archivo de proyecto

No hay. Todos los ficheros dentro de la carpeta del sitio web se incluyen automáticamente en el sitio.

Existe un fichero vbproj o csproj que almacena la lista de ficheros incluidos.

Excluir archivos del proyecto (menú contextual
Excluir del proyecto”)

Agrega la extensión .exclude

No agrega ninguna extensión al fichero, simplemente actualiza el archivo de proyecto (vbproj) para no incluirlo.

Archivo copiado en la carpeta de proyecto

Lo agrega automáticamente.

No lo agrega automáticamente. Es necesario pulsar la opción “Incluir en proyecto” en el menú contextual.

 

Una ventaja de usar archivos de proyecto en los proyectos de aplicación web es la siguiente:

“Es fácil quitar archivos del sitio temporalmente pero, aun así, asegúrese de no perder el control sobre ellos, dado que permanecen en la estructura de carpetas. Por ejemplo, si una página no está lista para implementarla, puede excluirla temporalmente de la compilación sin eliminarla de la estructura de carpetas. Puede implementar el ensamblado compilado y, a continuación, incluir de nuevo el archivo en el proyecto. “

Una ventaja de usar la estructura de carpetas sin archivos de proyecto en los proyectos de sitio web es la siguiente:

“No tiene que administrar la estructura del proyecto exclusivamente en Visual Studio. Por ejemplo, puede copiar archivos en el proyecto o eliminarlos de este mediante el Explorador de Windows.”

http://msdn.microsoft.com/es-es/library/dd547590.aspx

En cualquier caso, la funcionalidad de “Excluir archivos de proyecto” es igualmente válida con independencia del tipo de proyecto elegido. Esto es, si alguna página falla y queremos excluirla, podremos hacerlo en ambos tipos de proyecto.

 

Nuevo WebForm…

Default.aspx

·        Default.aspx.vb

WebForm1.aspx

·        WebForm1.designer.vb

·        WebForm1.aspx.vb

 

El fichero .designer.vb es un fichero autogenerado que no deberíamos nunca editar puesto que los cambios se perderían en un nuevo proceso de generación del fichero. En este fichero encontramos las declaraciones de los controles utilizados en el web form. Si alguna vez nos ocurre que hemos incluido un control en nuestro formulario pero no aparece en el fichero .designer.vb, la solución más rápida y efectiva parece ser borrar el fichero .designer.vb y en el menú contextual del formulario web pulsar la opción “Convertir en aplicación web” que volverá a crear el fichero .designer.vb con su contenido actualizado.

 

Clase de nuevo WebForm…

Nuevo Servicio Web…

[<Carpeta1>_][<CarpetaN_]_Default

En fichero .asmx se crea en la ubicación seleccionada, pero el fichero .vb se crea en el directorio App_Code.

WebForm1

Ambos ficheros se crean en la ubicación seleccionada.

 

Como vemos en la característica anterior, un sitio web crea un nuevo web form con una clase subyacente cuyo nombre es la lista de directorios concatenados más el nombre del fichero. De este modo, en un sitio web “no debería” haber nunca nombres de clases repetidos.  Por otro lado, esta convención de nombre de clase tiene el problema de que si se cambia de carpeta un web form, entonces el nombre de la clase ya no refleja su ubicación verdadero en el sitio.

Respecto a las aplicaciones web y puesto que no se antepone antes del nombre de clase ninguna información relativa a la carpeta donde está ubicado el elemento, podría pasar que hubiera nombres de clase repetidos. Por ejemplo, un web form Default.aspx en 2 carpetas distintas. Para solucionar esto, Visual Studio agrega un sufijo numérico al nombre de clase, de modo que en el ejemplo anterior tendríamos la clase _Default y _Default1.

 

Modelo de código

CodeFile

CodeFile="Default.aspx.vb" Inherits="Carpeta1_Default"

En un sitio web la clase Carpeta1_Default es parcial (que se une en tiempo de compilación con la clase del marcado), mientras que en una aplicación web la clase EsppacioDeNombres.Raiz._Default no es parcial.

CodeBehind

CodeBehind="Default.aspx.vb" Inherits="EspacioDeNombresRaiz._Default"

 

También es interesante observar que una aplicación web crea un espacio de nombres, mientras que un sitio web no lo crea. Por ello, en la aplicación web, el web form hereda de “<Espacio de nombres raíz>.<Clase>”.

 

App_Code

Es en la única carpeta (también en sus subcarpetas) donde se pueden guardar ficheros .vb.

Se puede guardar un fichero .vb en cualquier sitio del proyecto y compilará sin problemas.

Transportar el proyecto entre máquinas

Se puede abrir desde Visual Studio simplemente abriendo la carpeta principal del sitio web. Es fácil de transportar entre equipos de desarrollo.

Es necesario el archivo de proyecto (.vbproj o .csproj).

En mi opinión es más fácil de transportar este tipo de proyecto porque desde el principio (durante su creación) ya Visual Studio guarda todo lo necesario en una sola carpeta.

Compilación

Genera 1 fichero .dll por cada página, control, etc (si se especifica, sino 1 por carpeta, ver más abajo el punto “Publicación de sitio web”)

Se genera 1 sólo fichero .dll con toda la aplicación (páginas, controles de usuario, código del proyecto de la aplicación web, etc.)

 

Compilación - Rendimiento

Es complicado determinar que es más óptimo en términos de rendimiento, si 1 fichero .dll por página/carpeta (sitio web) o 1 sólo fichero para toda la aplicación (aplicación web). La primera solución es mejor si una navegación típica por nuestro sitio no implica cargar todas las páginas (sólo se carga lo necesario), sin embargo es mejor la segunda si por norma se navegará por todas las páginas (mejor cargar todo y así después no habrá tiempos de demora por cargar cada .ddl por separado).

Además, en memoria ocupa menos 1 .dll para toda la aplicación que lo que ocuparían todas las .ddl por página sumadas al final.

Por otro lado, también es cierto que 1 sólo fichero .dll para toda la aplicación tardará más en cargar la primera vez en memoria, pero a la larga será más rápido que esperar a cargar 1 .dll por página siempre la primera vez que se visita esa página.

No quiero olvidar decir que si el servidor anda corto de memoria, quizás parezca mejor de nuevo la primera opción puesto que aunque penalicemos el tiempo de carga por carga 1 .dll según la vamos necesitando, por contrapartida consumiremos sólo la memoria necesaria.

Compilación - Mantenimiento

En el caso de un sitio web, si una página cambia se puede sólo actualizar la .dll que la contiene y sin tocar el resto y todo debería funcionar. Sin embargo, en una aplicación web, cualquier cambio y por mínimo que sea, implicará compilar de nuevo todo el proyecto en 1 sólo fichero .dll y volver a subirlo entero.

Otra nota relacionada con la compilación, es que un sitio web utilizado ficheros .refresh para las copias locales de ensamblados en el directorio \bin, mientrás que una aplicación web no utilizar ficheros .refresh.La teoría dice que los ficheros .refresh (que guardan la ubicación en disco desde donde se agregó la referencia al ensamblado) sirve para si se cambia el fichero original que el sitio web actualice automáticamente el fichero (yo nunca he hecho esto y además me parece “demasiado” automático).

Un fichero .refresh se puede eliminar sin problemas, al igual que si lo copiamos de nuevo se “asociará” automáticamente a su fichero padre. De hecho si se quita el fichero .refresh vemos como en la página de propiedades del sitio web y para la referencia oportuna, el texto “Actualización automática” cambia automáticamente al número de versión del fichero.

Con ,refresh

image

Sin .refresh

image

 

Debug
/Release

Al no haber un fichero de proyecto no se manejan estos conceptos.
El único setting reseñable es debug=”true|false” del fichero web.config.

Funciona con normalidad como cualquier proyecto de Windows Forms.
Además también es importante de nuevo el setting debug=”true|false” del fichero web.config.

Publicación

1. xcopy

2. Se puede precompilar en el equipo local y después utilizar xcopy. Si no se precompila la compilación es realizada en tiempo de ejecución y de forma dinámica por ASP.NET la primera vez que se solicita un recurso.

Visual Studio permite publicar en:

·        Sistema de archivos

·        IIS Local

·        Sitio FTP

·        Sitio remoto

1. Copiar el ensamblado en el servidor. El ensamblado se genera al compilar la aplicación.

Visual Studio permite publicar en:

·        WebDeploy

·        FTP

·        Sistema de archivos

·        FPSE (Sitio remoto IIS con extensiones de servidor de FrontPage).

Análisis de código

No soportado.

Funciona.

Diagrama de capas

No soportado.

Funciona.

Atributos del ensamblado (nombre, versión, etc.)

No.

Sí.

Probar páginas sin tener en cuenta el estado de otras páginas (olvidándonos de que podemos “excluir” ficheros)

Sí (siempre y cuando no se precompile y se publique con xcopy).

Se pueden probar páginas específicas sin tener en cuenta el estado de otras páginas. Esto se debe a que la ejecución de una página individual no requiere la compilación correcta del sitio al completo, solo de la página y de los componentes de los que dependa, como el código de la carpeta App_Code o el archivo Global.asax.

No.

Referencias a otros proyectos web

No.

Sí.

Pre-build y post-build.

No.

Sí.

Acceso a páginas o controles de usuario desde clases independientes.

No.

Sí.

Compilar y publicar en sitio web

clip_image006

Permitir que este sitio precompilado se actualice

Especifica que el contenido de las páginas .aspx (importante!, sólo la parte del marcado) no se compila en un ensamblado, sino que el marcado se deja tal cual, lo cual permite realizar cambios en la funcionalidad del cliente y el código HTML después de precompilar el sitio Web.

Por ejemplo, si se deja marcada esta opción (por defecto),  en la carpeta de publicación seleccionada tendremos un fichero Default.aspx con el siguiente código:

<%@ page language="VB" autoeventwireup="false" inherits="_Default, App_Web_3eaft2cx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <h1>

            Hola Mundo</h1>

    </div>

    </form>

</body>

</html>

Sin embargo, si desmarcamos la opción tendremos esta otra salida para el fichero Default.aspx:

Éste es un archivo marcador generado por la herramienta de precompilación y que no se debería eliminar

En el primer caso podríamos editar en el servidor de producción la página .aspx (el marcado, diseño, etc.) y la aplicación reflejaría automáticamente los cambios. Sin embargo, en el segundo caso no podremos editar el fichero .aspx puesto que no tenemos disponible el marcado. Lo cierto es que nunca he tenido que modificar el marcado en producción y en mi opinión es preferible desmarcar esta opción porque además así tampoco distribuimos “parte” de nuestro código fuente (vale que el marcado no suele ser lo más interesante de nuestro trabajo intelectual, pero yo soy muy “quisquilloso” con esto…)

Por otro lado, fijarse como en el primer caso el atributo Inherits de la directiva Page apunta a la clase _Default y un ensamblado llamado App_Web_3eaft2cx. Pues bien, este ensamblado podremos ver que está disponible en la carpeta bin. De hecho, si abrimos este ensamblado con reflector (http://www.red-gate.com/products/reflector/), podemos ver que este ensamblado contiene tanto a nuestra clase _Default como a Default2 (luego ha compilado en un solo ensamblado todas las páginas .aspx de un mismo directorio).

De hecho y aunque en este documento se ha dicho que un sitio web genera 1 ensamblado por página, en realidad se genera 1 ensamblado por directorio, y concretamente para el directorio App_Code se genera 1 sólo ensamblado (con independencia de los subdirectorios que tenga).

 

clip_image008

Utilizar nomenclatura fija y ensamblados de una sola página

Con la situación anterior de ensamblados generados (y con independencia de si utilizamos “Permitir que este sitio precompilado se actualice”) es aún un poco difícil subir cambios realizados en una página al servidor de producción sin tener que publicar de nuevo. Esto se entiende porque cada vez que precompilamos los nombres de los ensamblados (a excepción del ensamblado App_Code.dll) son autogenerados y distintos para cada compilación. Por ejemplo, si quisiéramos hacer un cambio en Default.aspx.vb y publicar sólo la .ddl generada para su carpeta, tendríamos que saber que la antigua .ddl (la que borraremos del servidor de producción) se llama App_Web_3eaft2cx y la nueva se llama App_Web_<OtroID>, además de también sobreescribir Default.aspx y Default2.aspx (todos los ficheros .aspx de la carpeta)… uff, muy complicado, casi publico de nuevo todo y me quito de líos…

Pues bien, para solucionar este galimatías podemos activar “Utilizar nomenclatura fija y ensamblados de una sola página”, que generará:

Página Default.aspx con

<%@ page language="VB" autoeventwireup="false" inherits="_Default, App_Web_default.aspx.cdcab7d2" %>

Y un ensamblado en la carpeta bin con el nombre:

App_Web_default.aspx.cdcab7d2.ddl

De este modo, ya tenemos 1 ensamblado por página y además el nombre del ensamblado incluye el nombre de clase con lo que será fácilmente localizable.

Cabe mencionar que App_Code sigue generando 1 sólo ensamblado aunque marquemos está opción.

Por último, también decir que si marcamos esta opción estamos hablando de “compilación fija” (1 página – 1 ensamblado) y si no hablamos de “compilación por lotes” (1 carpeta – 1 ensamblado).

Ubicación

Por defecto se sugiere C:\Users\<Usuario>\Documents\Visual Studio 2010\Projects\<CarpetaProyecto>\PrecompiledWeb \<NombreProyecto>

En cualquier caso podemos elegir para la ubicación destino:

1.      Sistema de archivos (que si no es una ruta de red apuntando al servidor de producción, implicará que después de precompilar habría que copiar el resultado obtenido en la carpeta del servidor de producción).

2.      IIS Local (donde además podemos crear una nueva aplicación web o un directorio virtual si procede antes de publicar).

3.      Sitio FTP

4.      Sitio remoto

clip_image010

clip_image012

Compilar y Publicar en aplicación web

En una aplicación web no existe el concepto de precompilar porque tampoco se puede hacer xcopy del proyecto sin más en el servidor de producción y esperar que funcione, porque fallaría!. Esto es debido a que a diferencia del sitio web, una aplicación web es un proyecto (con su fichero vbproj asociado) y si quisiéramos hacer un xcopy, lo más parecido sería generar y copiar después el fichero <NombreAplicación>.dll que se haya generado en la carpeta bin.

Para publicar tenemos disponibles los siguientes métodos:

·        WebDeploy

·        FTP

·        Sistema de archivos

o   Sistema de archivos

o   IIS Local

·        FPSE

clip_image014

WebDeploy escapa al objetivo de este post, pero simplemente decir que es un nuevo método de publicación basado en paquetes que una vez configurado en el servidor de producción de IIS, permite al desarrollador subir las aplicaciones de una forma óptima y controlando números parámetros de la publicación (tanto IIS como de Sql Server), además también facilita a los administradores de IIS, la gestión, administración y migración de aplicaciones. Para saber más sobre WebDeploy, visitar http://javierholguera.com/technoblog/?p=104.

Respecto a la publicación de una aplicación web cabe mencionar que los ficheros aspx no se precompilan y que será en tiempo de ejecución cuando se compilen la primera vez que se soliciten. Esto se puede solucionar utilizando un proyecto de instalación web.

Por ende y a menos que se utilice un proyecto de instalación web, el código fuente de marcado de las páginas .aspx será público y accesible desde el servidor de producción (sólo el marcado).

Además y si fuera necesario, también es posible cambiar la ubicación del fichero .ddl de aplicación para que no esté necesariamente en la carpeta bin.

¿Y si no precompilamos un sitio web o no hacemos un proyecto de instalación web para una aplicación web?

Pues en este caso, IIS compilará en tiempo de ejecución el recurso solicitado la primera vez que un cliente lo solicite.

Cabe mencionar que en este escenario de compilación en tiempo de ejecución, la compilación es “por lotes”, esto es que se compila la carpeta entero donde está el recurso. Además, el primer recurso solicitado también compilará Global.asax (si existe) y también sólo 1 recurso será el encargado de compilar la carpeta App_Code (si la utiliza).

Con esto, se puede deducir que por norma, el primer acceso a la primera página será un poco más lento (Global.asax, normalmente también App_Code) y siguientes accesos a recursos en otros directorios también serán un poco más lentos.

Otras diferencias menores

En un sitio web al agregar un nuevo elemento:

clip_image016

En una aplicación web:

clip_image018

Como vemos la principales diferencias son el nombre de la página .aspx sugerida (Default vs WebForm) y como seleccionamos la página maestra.

Otra diferencia es como aparece la página en la lista de eventos y al nombre que automáticamente escoge Visual Studio al seleccionar un evento de la lista:

En un sitio web:

clip_image020

En una aplicación web:

clip_image022

Por ende si seleccionamos por ejemplo el evento PreRender, tendremos un nombre de evento distinto (aunque ambos finalmente “manejan” el mismo evento).

En un sitio web:

    Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender

    End Sub

En una aplicación web:

    Private Sub WebForm1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender

    End Sub

Además también deberíamos apreciar que por defecto en un sitio web el alcance de visibilidad de los métodos es “Protected”, mientras que en una aplicación web es “Private”. Realmente no parece muy relevante, sólo tener cuidado si enlazamos los eventos de los controles a través del atributo “On<Evento>” desde el marcado, puesto que entonces el alcance del método debería ser mínimo “Protected” (con “Private” no funcionará).

Referencias a ensamblados

Otra diferencia que me he encontrado hoy es que, si trabajamos con .NET Framework 4.0, me queda mucho más claro en una aplicación web, cuales ensamblados estamos referenciando.

Lo que quiero decir es que una aplicación web no hay perdida alguna. Sabemos exactamente que estamos referenciando. Esta información se guarda en el fichero .vbproj y además podemos ver las referencias tanto en el nodo “References” (activando ver ficheros ocultos para el proyecto) como en las propiedades del proyecto, en la pestaña “Referencias”.

Sin embargo, en un sitio web, esta información se guarda en el fichero web.config (porque logicamente no hay ningún fichero de proyecto donde guardarlas), así que las secciones <system.web><assemblies>… y <system.web><pages><namespaces>… son las que guardan tanto la información de los ensamblados referenciados como los espacios de nombres importados.

Para más inri, con el nuevo modelo de fichero web.config de ASP.NET 4.0 http://weblogs.asp.net/scottgu/archive/2009/08/25/clean-web-config-files-vs-2010-and-net-4-0-series.aspx, directamente hay algunas referencias que “mágicamente” tenemos disponibles en un sitio web pero que no podemos saber cuales son, es decir, no aparecen en el cuadro de diálogo propiedades del sitio web.

Editar y continuar

Claramente apuesto con un proyecto de aplicación web pero aún tengo pendiente poder “Editar y Continuar” en el código de mis páginas .aspx.

Juro haber navegado hasta la saciedad en google para encontrar una respuesta, pero todas me han llevado a seguir frustrado con este tema (deshabilitar IntelliTrace, activar Editar y Continuar, etc.). Imagino que quizás un futuro Service Pack ayuda a implementar esta funcionalidad.

Bibliografía

http://msdn.microsoft.com/es-es/library/dd547590.aspx

http://geeks.ms/blogs/jalarcon/archive/2009/01/18/sitios-web-o-aplicaciones-web-en-visual-studio-2005-2008-191-cu-225-l-utilizar.aspx

http://eloyparedes.wordpress.com/2007/07/17/proyectos-de-aplicacion-web-vs-proyectos-de-sitio-web-web-application-projects-vs-web-site-projects/

http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx

6 comentarios:

  1. buen articulo muchas gracias, solo una duda, En un proyecto tipo Aplicacion web, puedo usar herencia de webforms, cosa que no puedo hacer con el de sitio web.
    alguna sugerencia

    ResponderEliminar
    Respuestas
    1. Hola jhonny, no se si por "herencia de webforms" te refieres a crear una clase de la que hereda después System.Web.UI.Page. Sí es así, se puede hacer en ambos tipos de proyecto sin problemas. Yo por ejemplo suelo hacer siempre una clase PageBase de la que después heredan todos mis webforms (ya sea sitio web o aplicación web).
      Un saludo.

      Eliminar
  2. Gracias por la aclaración, al menos para mi ha sido muy util!!

    ResponderEliminar
  3. Hola compañero!
    Suelo trabajar casi siempre con Sitio web: SIempre he sido yo sólo desarrollando aplicaciones, pero ultimamente se ha incorporado un compañero nuevo y queremos trabajar simultaneamente en un mismo proyecto. Es necesario instalat TFS o se puede hacer sin necesidad de tanta parafernalia? NBo se si tienes experiencia en esto
    Gracias

    ResponderEliminar
  4. Hola:
    Yo creo que lo mejor sería instalar un TFS o similar. Fíjate que ahora mismo tienes muchas opciones gratis como SVN, TFS Service, TFS Express, etc (todos ellos con plug-in para Visual Studio para que todo sea coser y cantar). Si no instalar ningún software de control de versiones, lo mejor sería trabajar contra un IIS (local o un servidor) y entonces tú y tu compañero trabajaríais en el mismo proyecto... pero cuidado de no editar el mismo fichero a la vez ;-) Sin duda, lo mejor un TFS express o service.
    Un saludo.

    ResponderEliminar
  5. hola tengo una duda con los .dll que se generan de las paginas, cuando migro un proyecto...he migrado un proyecto web a una aplicación web, a la hora de hacer esto los .dll de las paginas deberían auto generarse?, solo solo lo debería hacer el .dll de la aplicación?

    ResponderEliminar