Skip to content

3. Introducción al desarrollo web ASP.NET

3.1. Introduction

En el capítulo anterior se presentaron los principios del desarrollo web, que son independientes del lenguaje de programación utilizado. Actualmente, tres tecnologías dominan el mercado del desarrollo web:

  • J2EE, que es una plataforma de desarrollo en Java. En combinación con la tecnología Struts, instalada en diversos servidores de aplicaciones, la plataforma J2EE se utiliza principalmente en proyectos de gran envergadura. Debido al lenguaje utilizado —Java—, una aplicación J2EE puede funcionar en los principales sistemas operativos (Windows, Unix, Linux, Mac OS, ...)
  • PHP, que es un lenguaje interpretado, también independiente del sistema operativo. A diferencia de Java, no es un lenguaje orientado a objetos. Sin embargo, se espera que la versión PHP5 introduzca los objetos en el lenguaje. De fácil acceso, PHP se utiliza ampliamente en proyectos pequeños y medianos.
  • ASP.NET es una tecnología que solo funciona en equipos con Windows que cuenten con la plataforma .NET (XP, 2000, 2003, ...). El lenguaje de desarrollo que se puede utilizar es cualquier lenguaje compatible con .NET, c.a.d. Hay más de una decena, empezando por los lenguajes de Microsoft (C#, VB.NET, J#), Delphi de Borland, Perl, Python, ...

En el capítulo anterior se presentaron ejemplos breves de cada una de estas tres tecnologías. Este documento se centra en el desarrollo web ASP.NET con el lenguaje VB.NET. Suponemos que ya se conoce este lenguaje. Este punto es importante. Aquí nos enfocamos únicamente en su uso en el contexto del desarrollo web. Aclaremos mejor este punto al hablar de la metodología MVC para el desarrollo web.

Una aplicación web que siga el modelo MVC tendrá la siguiente arquitectura:

Image

Esta arquitectura, conocida como de tres capas o de tres niveles, busca cumplir con el modelo MVC (Model View Controller):

  • la interfaz de usuario es la V (la vista)
  • la lógica de la aplicación es el C (el controlador)
  • las fuentes de datos son el M (Modelo)

La interfaz de usuario suele ser un navegador web, pero también podría ser una aplicación independiente que, a través de la red, enviara solicitudes HTTP al servicio web y diera formato a los resultados que este le envía. La lógica de la aplicación está compuesta por los scripts que procesan las solicitudes del usuario. La fuente de datos suele ser una base de datos, pero también pueden ser simples archivos planos, un directorio LDAP, un servicio web remoto, etc. Es recomendable que el desarrollador mantenga una gran independencia entre estas tres entidades, de modo que, si una de ellas cambia, las otras dos no tengan que cambiar, o solo lo hagan mínimamente.

  • La lógica de negocio de la aplicación se colocará en clases separadas de la clase que controla el diálogo de solicitud-respuesta. De este modo, el bloque [Logique applicative] anterior podría estar compuesto por los siguientes elementos:

Image

En el bloque [Logique Applicative], se podrá distinguir

  • la clase controladora, que es la puerta de entrada a la aplicación,
  • el bloque [Classes métier], que agrupa las clases necesarias para la lógica de la aplicación. Estas son independientes del cliente.
  • el bloque [Classes d'accès aux données], que agrupa las clases necesarias para obtener los datos que requiere el servlet, a menudo datos persistentes (BD, archivos, servicio WEB, ...)
  • el bloque de páginas ASP, que constituye las vistas de la aplicación.

En los casos sencillos, la lógica de la aplicación suele reducirse a dos clases:

  • la clase controladora, que se encarga del diálogo entre el cliente y el servidor: procesamiento de la solicitud, generación de las distintas respuestas
  • la clase de negocio, que recibe del controlador los datos que debe procesar y le devuelve los resultados. Esta clase de negocio gestiona entonces por sí misma el acceso a los datos persistentes.

La particularidad del desarrollo web radica en la programación de la clase controladora y de las páginas de presentación. Las clases de negocio y de acceso a datos son clases .NET clásicas que pueden utilizarse tanto en una aplicación web como en una aplicación de Windows o incluso de tipo consola. La programación de estas clases requiere un buen conocimiento de la programación orientada a objetos. En este documento, se escribirán en VB.NET, por lo que suponemos que se domina este lenguaje. Desde esta perspectiva, no hay necesidad de detenerse más de lo necesario en el código de acceso a los datos. En casi todos los libros sobre ASP.NET, se dedica un capítulo a ADO.NET. El diagrama anterior muestra que el acceso a los datos se realiza mediante clases .NET totalmente convencionales que ignoran que se utilizan en un contexto web. El controlador, que es el líder del equipo de la aplicación web, no tiene que preocuparse por ADO.NET. Solo debe saber a qué clase debe solicitar los datos que necesita y cómo solicitarlos. Eso es todo. Incluir código ADO.NET en el controlador no se ajusta al concepto MVC explicado anteriormente y no lo haremos.

3.2. Las herramientas

Este documento está dirigido a estudiantes, por lo que trabajaremos con herramientas gratuitas que se pueden descargar de Internet:

  • la plataforma .NET (compiladores, documentación)
  • el entorno de desarrollo WebMatrix, que incluye el servidor web Cassini
  • diferentes SGBD (MSDE, MySQL)

Se invita al lector a consultar el anexo «Herramientas web», que indica dónde encontrar y cómo instalar estas diferentes herramientas. En la mayoría de los casos, solo necesitaremos tres herramientas:

  • un editor de texto para escribir las aplicaciones web.
  • una herramienta de desarrollo VB.NET para escribir el código VB cuando este sea extenso. Este tipo de herramienta suele ofrecer ayuda para la escritura de código (autocompletado) y la detección de errores sintácticos, ya sea al escribir el código o durante la compilación.
  • un servidor web para probar las aplicaciones web desarrolladas. En este documento se utilizará Cassini. El lector que cuente con el servidor IIS podrá sustituir Cassini por IIS. Ambos son compatibles con .NET. Sin embargo, Cassini está limitado a responder únicamente a solicitudes locales (localhost), mientras que IIS puede responder a solicitudes de máquinas externas.

Un excelente entorno comercial para desarrollar en VB.NET es Visual Studio.NET de Microsoft. Este IDE, con amplias funcionalidades, permite gestionar todo tipo de documentos (código VB.NET, documentos HTML, XML, hojas de estilo, etc.). Para la escritura de código, ofrece la valiosa ayuda de la “autocompletación” automática. Dicho esto, esta herramienta, que mejora notablemente la productividad del desarrollador, tiene una desventaja derivada de sus propias cualidades: limita al desarrollador a un modo de desarrollo estándar que, si bien es eficaz, no siempre resulta adecuado.

Es posible utilizar el servidor Cassini fuera de [WebMatrix] y es lo que haremos con frecuencia. El ejecutable del servidor se encuentra en <WebMatrix>\<versión>\WebServer.exe, donde <WebMatrix> es el directorio de instalación de [WebMatrix] y <versión> es su número de versión:

Image

Abramos una ventana de DOS y naviguemos hasta la carpeta del servidor Cassini:

E:\Program Files\Microsoft ASP.NET Web Matrix\v0.6.812>dir
...
29/05/2003  11:00               53 248 WebServer.exe
...

Ejecutemos [WebServer.exe] sin parámetros:

E:\Program Files\Microsoft ASP.NET Web Matrix\v0.6.812>webserver

Image

El panel anterior nos indica que la aplicación [WebServer/Cassini] admite tres parámetros:

  • /port: número de puerto del servicio web. Puede ser cualquiera. El valor predeterminado es 80
  • /path: ruta física de una carpeta en el disco
  • /vpath: carpeta virtual asociada a la carpeta física anterior.

Colocaremos nuestros ejemplos en una estructura de archivos con raíz P, que contiene las carpetas chap1, chap2, ... para los distintos capítulos de este documento. Asociaremos a esta carpeta física P la ruta virtual V. Por lo tanto, ejecutaremos Cassini con el siguiente comando de DOS:

dos> WebServer /port:80 /path:P vpath:V

Por ejemplo, si queremos que la raíz física del servidor sea la carpeta [D:\data\devel\aspnet\poly] y su raíz virtual [aspnet], el comando de DOS para iniciar el servidor web será:

dos> WebServer /port:80 /path:D:\data\devel\aspnet\poly vpath:/aspnet

Este comando se puede agregar a un acceso directo. Una vez iniciado, Cassini coloca un ícono en la barra de tareas. Al hacer doble clic en él, se accede a un panel de encendido/apagado del servidor:

Image

El panel muestra los tres parámetros con los que se inició. Cuenta con dos botones de encendido/apagado, así como un enlace de prueba hacia la raíz de su árbol web. Lo seguimos. Se abre un navegador y se solicita la página URL [http://localhost/aspnet]. Obtenemos el contenido de la carpeta indicada en el campo [Physical Path] anterior:

Image

En el ejemplo, la solicitud URL corresponde a una carpeta y no a un documento web, por lo que el servidor mostró el contenido de esa carpeta y no un documento web específico. Si en esa carpeta existe un archivo llamado [default.aspx], este se visualizará. Creemos, por ejemplo, el siguiente archivo y coloquémoslo en la raíz del árbol web de Cassini (d:\data\devel\aspnet\poly en este caso):

<html>
    <head>
        <title>Page d'entrée</title>
    </head>
    <body>
    Page d'index...
    </body>
</html>
dos>dir d:\data\devel\aspnet\poly\default.aspx
23/03/2004  18:21                  107 default.aspx

Ahora solicitemos el URL [http://localhost/aspnet] con un navegador:

Image

Se observa que, en realidad, lo que se ha mostrado es el URL [http://localhost/aspnet/default.aspx]. Más adelante en este documento, explicaremos cómo se debe configurar Cassini mediante la notación Cassini(path,vpath), donde [path] es el nombre de la carpeta raíz del árbol web del servidor y [vpath] es la ruta virtual asociada. Recordemos que, con el servidor Cassini(path,vpath), la URL [http://localhost/vpath/XX] corresponde a la ruta física [path\XX]. Colocaremos todos nuestros documentos en una raíz física a la que llamaremos <webroot>. De esta manera, podremos referirnos al archivo <webroot>\chap2\here1.aspx. Para cada lector, esta raíz <webroot> será una carpeta en su computadora personal. Aquí, las capturas de pantalla mostrarán que esta carpeta suele ser [d:\data\devel\aspnet\poly]. Sin embargo, no siempre será así, ya que las pruebas se realizaron en computadoras diferentes.

3.3. Primeros ejemplos

Presentaremos ejemplos sencillos de páginas web dinámicas creadas con VB.NET. Invitamos al lector a probarlos para verificar que su entorno de desarrollo esté correctamente instalado. Descubriremos que hay varias formas de construir una página ASP.NET. Elegiremos una de ellas para continuar con nuestros desarrollos.

3.3.1. Ejemplo básico - variante 1

Herramientas necesarias: un editor de texto, el servidor web Cassini

Retomamos el ejemplo del capítulo anterior. Creamos el siguiente archivo [heure1.aspx]:

<html>
  <head>
      <title>Demo asp.net </title>
  </head>
  <body>
      Il est <% =Date.Now.ToString("T") %>
  </body>
</html>

Este código es del tipo HTML con una etiqueta especial <% ... %>. Dentro de esta etiqueta, se puede incluir código VB.NET. Aquí el código

Date.Now.ToString("T")

genera una cadena de caracteres C que representa la hora actual. La etiqueta <% ... %> se reemplaza entonces por esta cadena de caracteres C. Así, si C es la cadena 18:11:01, la línea HTML que contiene el código VB.NET queda así:

      Il est 18:11:01

Colocamos el código anterior en el archivo [<webroot>\chap2\heure1.aspx]. Iniciamos Cassini (<webroot>,/aspnet) y solicitamos con un navegador el archivo URL [http://localhost/aspnet/chap2/heure1.aspx]:

Image

Una vez obtenido este resultado, sabemos que el entorno de desarrollo está correctamente instalado. La página [heure1.aspx] se ha compilado, ya que contiene código VB.NET. Su compilación generó un archivo DLL que se guardó en una carpeta del sistema y luego fue ejecutado por el servidor Cassini.

3.3.2. Ejemplo básico - variante 2

Herramientas necesarias: un editor de texto, el servidor web Cassini

El documento [heure1.aspx] combina código HTML y código VB.NET. En un ejemplo tan sencillo, esto no representa ningún problema. Si se necesita incluir más código VB.NET, será conveniente separar aún más el código HTML del código VB. Esto se puede lograr agrupando el código VB dentro de una etiqueta <script>:

<script runat="server">
     ' cálculo de los datos que se mostrarán mediante el código HTML
...
</script>
<html>
....
' visualización de los valores calculados por la parte de script
</html>

El ejemplo [heure2.aspx] ilustra este método:

<script runat="server">
    Dim maintenant as String=Date.Now.ToString("T")
</script>
<html>
    <head>
        <title>Demo asp.net </title>
    </head>
    <body>
        Il est
        <% =maintenant %>
    </body>
</html>

Colocamos el documento [heure2.aspx] en la estructura de directorios [<webroot>\chap2\heure2.aspx] del servidor web Cassini (<webroot>,/aspnet) y solicitamos el documento con un navegador:

Image

3.3.3. Ejemplo básico - variante 3

Herramientas necesarias: un editor de texto, el servidor web Cassini

Llevamos más allá el proceso de separación del código VB y del código HTML al colocarlos en dos archivos distintos. El código HTML estará en el documento [heure3.aspx] y el código VB en [heure3.aspx.vb]. El contenido de [heure3.aspx] será el siguiente:


<%@ Page Language="vb" src="heure3.aspx.vb" Inherits="heure3" %>
<html>
    <head>
        <title>Demo asp.net</title>
    </head>
    <body>
        Il est
        <% =maintenant %>
    </body>
</html>

Hay dos diferencias fundamentales:

  • la directiva [Page] con atributos aún desconocidos
  • el uso de la variable [maintenant] en el código HTML, a pesar de que no está inicializada en ningún lado

La directiva [Page] sirve aquí para indicar que el código VB, que inicializará la página, se encuentra en otro archivo. Es el atributo [src] el que lo indica. Veremos que el código VB corresponde a una clase llamada [heure3]. De manera transparente para el desarrollador, un archivo .aspx se transforma en una clase que deriva de una clase base llamada [Page]. En este caso, nuestro documento HTML debe derivarse de la clase que define y calcula los datos que debe mostrar. Aquí se trata de la clase [heure3], definida en el archivo [heure3.aspx.vb]. Asimismo, debemos indicar esta relación padre-hijo entre el documento VB [heure3.aspx.vb] y el documento HTML [heure3.aspx]. Es el atributo [inherits] el que especifica esta relación. Debe indicar el nombre de la clase definida en el archivo al que apunta el atributo [src].

Ahora analicemos el código VB de la página:

Public Class heure3
    Inherits System.Web.UI.Page

     ' datos de la página web que se mostrarán
    Protected maintenant As String

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         'se calculan los datos de la página web
        maintenant = Date.Now.ToString("T")
    End Sub
End Class

Cabe destacar los siguientes puntos:

  • el código VB define una clase [heure3] derivada de la clase [System.Web.UI.Page]. Esto siempre es así, ya que una página web siempre debe derivarse de [System.Web.UI.Page].
  • La clase declara un atributo protegido (protected) [maintenant]. Sabemos que un atributo protegido es accesible directamente en las clases derivadas. Esto es lo que permite que el documento HTML y [heure3.aspx] tengan acceso al valor del dato [maintenant] en su código.
  • La inicialización del atributo [maintenant] se realiza en un procedimiento [Page_Load]. Más adelante veremos que el servidor web notifica a un objeto de tipo [Page] una serie de eventos. El evento [Load] ocurre cuando se han creado el objeto [Page] y sus componentes. El manejador de este evento se designa mediante la directiva [Handles MyBase.Load]
    Private Sub XX(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  • El nombre [XX] del manejador del evento puede ser cualquiera. Su firma debe ser la indicada anteriormente. No explicaremos esto por el momento.
  • A menudo se utiliza el controlador de eventos [Page.Load] para calcular los valores de los datos dinámicos que debe mostrar la página web.

Los documentos [heure3.spx] y [heure3.aspx.vb] se colocan en [<webroot>\chap2]. Luego, con un navegador, se solicita el URL y el [http://localhost/aspnet/chap2/heure3.aspx] al servidor web (<webroot>,/aspnet):

Image

3.3.4. Ejemplo básico - variante 4

Herramientas necesarias: un editor de texto, el servidor web Cassini

Mantenemos el mismo ejemplo que antes, pero volvemos a agrupar todo el código en un único archivo [heure4.aspx]:

<script runat="server">
     ' datos de la página web que se deben mostrar
    Private maintenant As String

     ' evt page_load
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         'se calculan los datos de la página web
        maintenant = Date.Now.ToString("T")
    End Sub
</script>

<html>
    <head>
        <title>Demo asp.net</title>
    </head>
    <body>
        Il est
        <% =maintenant %>
    </body>
</html>

Vemos la secuencia del ejemplo 2:

<script runat="server">
.... code VB
</script>

<html>
... code HTML
</html>

En esta ocasión, el código VB se ha estructurado en procedimientos. Se incluye el procedimiento [Page_Load] del ejemplo anterior. Aquí queremos mostrar que una página .aspx por sí sola (sin estar vinculada a un código VB en un archivo separado) se transforma implícitamente en una clase derivada de [Page]. Por lo tanto, se pueden utilizar los atributos, métodos y eventos de esta clase. Esto es lo que se hace aquí, donde se utiliza el evento [Load] de esta clase.

El método de prueba es idéntico a los anteriores:

Image

3.3.5. Ejemplo básico - variante 5

Herramientas necesarias: un editor de texto, el servidor web Cassini

Al igual que en el ejemplo 3, se separan el código VB y el código HTML en dos archivos distintos. El código VB se coloca en [heure5.aspx.vb]:

Public Class heure5
    Inherits System.Web.UI.Page

     ' datos de la página web que se mostrarán
    Protected maintenant As String

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         'se calculan los datos de la página web
        maintenant = Date.Now.ToString("T")
    End Sub
End Class

El código HTML se coloca en [heure5.aspx]:


<%@ Page Inherits="heure5" %>
<html>
    <head>
        <title>Demo asp.net</title>
    </head>
    <body>
        Il est
        <% =maintenant %>
    </body>
</html>

En esta ocasión, la directiva [Page] ya no indica la relación entre el código HTML y el código VB. El servidor web ya no puede localizar el código VB para compilarlo (falta el atributo src). Nos toca a nosotros realizar esta compilación. Por lo tanto, en una ventana de DOS, compilamos la clase VB [heure5.aspx.vb]:

dos>dir
23/03/2004  18:34                  133 heure1.aspx
24/03/2004  09:47                  232 heure2.aspx
24/03/2004  10:16                  183 heure3.aspx
24/03/2004  10:16                  332 heure3.aspx.vb
24/03/2004  14:31                  440 heure4.aspx
24/03/2004  14:45                  332 heure5.aspx.vb
24/03/2004  14:56                  148 heure5.aspx
dos>vbc /r:system.dll /r:system.web.dll /t:library /out:heure5.dll heure5.aspx.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>dir heure5.dll
24/03/2004  14:51                3 072 heure5.dll

En el ejemplo anterior, el ejecutable [vbc.exe] del compilador se encontraba en el directorio PATH del sistema DOS. De no haber sido así, habría sido necesario indicar la ruta completa de [vbc.exe], que se encuentra en el árbol de carpetas donde se instaló SDK.NET. Las clases derivadas de [Page] requieren recursos presentes en DLL y [system.dll, system.web.dll], de ahí que se haga referencia a ellas mediante la opción /r del compilador. La opción /t:library sirve para indicar que se desea generar un archivo DLL. La opción /out indica el nombre del archivo que se generará, en este caso [heure5.dll]. Este archivo contiene la clase [heure5] que necesita el documento web [heure5.aspx]. Sin embargo, el servidor web busca los archivos DLL que necesita en ubicaciones muy específicas. Una de estas ubicaciones es la carpeta [bin], ubicada en la raíz de su árbol de directorios. Esta raíz es lo que hemos denominado <webroot>. Para el servidor IIS, suele ser <unidad>:\inetpub\wwwroot, donde <unidad> es la unidad (C, D, ...) en el que se instaló IIS. Para el servidor Cassini, esta raíz corresponde al parámetro /path con el que lo iniciaste. Recuerda que este valor se puede obtener al hacer doble clic en el ícono del servidor en la barra de tareas:

Image

<webroot> corresponde al atributo [Physical Path] mencionado anteriormente. Por lo tanto, creamos una carpeta <webroot>\bin y colocamos [heure5.dll] en ella:

Image

Ya estamos listos. Solicitamos URL [http://localhost/aspnet/chap2/heure5.aspx] al servidor Cassini (<webroot>,/aspnet):

Image

3.3.6. Ejemplo básico - variante 6

Herramientas necesarias: un editor de texto, el servidor web Cassini

Hasta ahora hemos demostrado que una aplicación web dinámica tiene dos componentes:

  1. código VB para calcular las partes dinámicas de la página
  2. código HTML que, en ocasiones, incluye código VB para mostrar esos valores en la página. Esta parte representa la respuesta que se envía al cliente web.

El componente 1 se denomina componente controlador de la página y el componente 2, componente de presentación. El componente de presentación debe contener la menor cantidad posible de código VB, o incluso ningún código VB. Veremos que esto es posible. Aquí mostramos un ejemplo en el que solo hay un controlador y no hay componente de presentación. Es el controlador el que genera por sí mismo la respuesta al cliente sin la ayuda del componente de presentación.

El código de presentación queda así:

 <%@ Page src="heure6.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="heure6" %>

Se observa que ya no hay ningún código HTML en él. La respuesta se genera directamente en el controlador:

Public Class heure6
    Inherits System.Web.UI.Page

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         ' se elabora la respuesta
        Dim HTML As String
        HTML = "<html><head><title>heure6</title></head><body>Il est "
        HTML += Date.Now.ToString("T")
        HTML += "</body></html>"
         ' se envía
        Response.Write(HTML)
    End Sub
End Class

Aquí, el controlador genera la respuesta completa, en lugar de solo las partes dinámicas de la misma. Además, la envía. Lo hace mediante la propiedad [Response], de tipo [HttpResponse], de la clase [Page]. Se trata de un objeto que representa la respuesta que el servidor envía al cliente. La clase [HttpResponse] cuenta con un método [Write] para escribir en el flujo HTML que se enviará al cliente. Aquí, colocamos todo el flujo HTML que se va a enviar en la variable [HTML] y enviamos esta al cliente mediante [Response.Write(HTML)].

Solicitamos la URL [http://localhost/aspnet/chap2/heure6.aspx] al servidor Cassini (<webroot>,/aspnet):

Image

3.3.7. Conclusión

A continuación, utilizaremos el método 3, que coloca el código VB y el código HTML de un documento web dinámico en dos archivos separados. Este método tiene la ventaja de dividir una página web en dos componentes:

  1. un componente controlador compuesto únicamente por el código VB para calcular las partes dinámicas de la página
  2. un componente de presentación, que es la respuesta que se envía al cliente. Está compuesto por código HTML, que en ocasiones incluye código VB para mostrar los valores dinámicos. Siempre buscaremos tener la menor cantidad posible de código VB en la parte de presentación; lo ideal sería no tener nada.

Como se mostró en el método 5, el controlador se puede compilar independientemente de la aplicación web. Esto tiene la ventaja de permitirnos concentrarnos únicamente en el código y obtener, en cada compilación, la lista de todos los errores. Una vez compilado el controlador, se puede probar la aplicación web. Sin una compilación previa, será el servidor web el que la realice, y entonces los errores se señalarán uno por uno. Esto puede resultar tedioso.

Para los ejemplos que siguen, bastan las siguientes herramientas:

  • un editor de texto para crear los documentos HTML y VB de la aplicación cuando son sencillos
  • una herramienta de desarrollo .IDE para crear las clases VB.NET y así aprovechar la ayuda que este tipo de herramienta brinda al escribir código. Un ejemplo de dicha herramienta es CSharpDevelop (http://www.icsharpcode.net). En el anexo [Les outils du développement web] se muestra un ejemplo de uso.
  • la herramienta WebMatrix para crear las páginas de presentación de la aplicación (véase el anexo [Les outils du développement web]).
  • el servidor Cassini

Todas estas herramientas son gratuitas.