2013/09/02

Estructura de una aplicación ASP.NET MVC


Crear una aplicación ASP.NET MVC con Visual Studio

Ya hemos visto los fundamentos de una aplicación web y una introducción al patrón MVC. Llegados a esto punto ya podemos crear nuestra aplicación web con ASP.NET MVC. Para ello, abrimos Visual Studio, y a través del menú seleccionamos “New Project”. En el caso de que no tengamos instalado Visual Studio podemos descargar la versión Express (gratuita) desde el siguiente enlace: http://www.asp.net/mvc
image
Para crear una aplicación ASP.NET MVC basta con seleccionar la opción adecuada dentro de la pantalla de templates para Visual Studio. Seleccionamos ASP.NET MVC Web Applicattion. En el caso de que la opción no figure en al lista, es indicativo de que no hemos instalado ASP.NET MVC. Podemos realizar dicha descarga desde este enlace: http://www.asp.net/mvc
 image
En el siguiente paso debemos seleccionar la plantilla del proyecto. Disponemos de tres plantillas:
  • Empty – Plantilla vacia.
  • Internet Application – Plantilla de propósito general configurada con seguridad basada en formularios (la aplicación pedirá usuario y password al visitante para identificarse). Adecuada para aplicaciones de internet.
  • Intranet Application - Plantilla de propósito general configurada con seguridad basada en Windows, integrada con el directorio activo (la aplicación utiliza el usuario de Windows que esta conectado). Adecuada para entornos de intranet.
En nuestro caso seleccionamos “Internet Application”.
image
Es importante destacar que en la parte inferior de esta pantalla es en la que seleccionamos el motor de renderizado de las vistas «View Engine» - seleccionamos RAZOR. En ASP.NET MVC las vistas son procesadas por un motor de renderizado antes de ser devueltas al cliente. Este motor es RAZOR. En este mismo tutorial veremos en detalle la sintaxis de RAZOR.
Además disponemos de un segundo motor de renderizado – ASPX, que emplea la misma sintaxis utilizada por Web Forms (basado en las marcas <% %>)
También podemos instalar motores adicionales, como el caso de NHAML - http://code.google.com/p/nhaml/, una implementación de .NET del popular motor de renderizado de Ruby On Rails.
En esta pantalla – New ASP.NET MVC 4 Project -, seleccionamos además la casilla para crear un proyecto de «Testing» y el framework que deseamos utilizar para el mismo. Una de las ventajas que obtenemos al utilizar ASP.NET MVC es simplificar el proceso de test de nuestro código, algo importantísimo de cara a la calidad de nuestros desarrollos. Al final de este tutorial incluiremos un anexo sobre test unitario (mientras tanto os invito a la excelente introducción que realizo Ibon Landa en Geeks http://geeks.ms/blogs/ilanda/archive/2009/06/16/pruebas-unitarias-resumiendo.aspx)
Finalmente, pulsamos OK y Visual Studio creará el proyecto.
Al finalizar, debemos tener una solución de Visual Studio con una estructura como la siguiente:
image
Como podemos ver la imagen anterior Visual Studio ha creado una solución con dos proyectos:
  • MvcApplication1, se trata del proyecto web que contiene los archivos de nuestra aplicación web.
  • MvcApplication1.Test, es el proyecto de testing asociado.
A continuación vamos a explicar los diferente archivos y directorios que se han creado en el proyecto MvcApplication1, con el objetivo de entender la organización de ficheros y carpetas de ASP.NET MVC.
Profundizaremos en los diferentes conceptos según avancemos en el tutorial, se muestran aquí de manera introductoria para que nos vayamos familiarizando con la estructura de archivos y carpetas.

Estructura de directorios y archivos.

Cuando creamos una nueva aplicación con ASP.NET MVC se crea por defecto una estructura de directorios, apropiada para la gran mayoría de las aplicaciones. Por supuesto podemos añadir nuevos directorios a esta estructura, aunque por razones de coherencia recomendamos mantener la estructura que propone ASP.NET MVC.

Directorio App_Data.

Este directorio está pensado para ubicar archivos de datos, normalmente bases de datos MSSQL. También es el lugar adecuado para archivos XML o cualquier otra fuente de datos.
Inicialmente está vacio.

Directorio App_Start.

Este directorio, nuevo en ASP.NET MVC 4, contiene los archivos de código que se ejecutan al inicializar la aplicación. Como veremos mas adelante, todo aplicación ASP.NET MVC es una instancia derivada de la clase System.Web.HttpApplication, definida en el archivo global.asax. Esta clase es la encargada de iniciar la aplicación, el directorio App_Start está pensando para ubicar las clases de configuración para el inicio de la aplicación.
La siguiente imagen muestra el contenido del directorio.
image
Por defecto contiene los siguientes archivos(clases):
  • AuthConfig.cs
  • BundleConfig.cs
  • FilterConfig.cs
  • RouteConfig.cs
  • WebApiConfig.cs

Directorio Content.

El directorio Content está pensado para el contenido estático de la aplicación, especialmente útil para archivos css e imágenes asociadas.
image
ASP.NET MVC nos ofrece por defecto una organización en base a “temas”, que nos permita personalizar el aspecto visual de nuestra aplicación de forma fácil y rápida (eso en teoría… elaborar un tema visual puede requerir de mucho trabajo y la colaboración de un diseñador gráfico, algo que recomiendo siempre que sea posible).
También es el lugar apropiado para los archivos .less en el caso de que utilicemos esta tecnología en nuestra aplicación.

Directorio Controllers.

El directorio controllers en el lugar para los controladores, que como hemos visto en el capitulo anterior  los controladores son las clases encargadas de recibir y gestionar las peticiones http de la aplicación.
image
Veremos los controladores en profundidad mas adelante.

Directorio Filters

El directorio Filters es el lugar donde debemos ubicar los filtros. Los filtros son atributos (también llamados decoradores) para los controladores, que nos permiten aplicar un comportamiento previo y posterior a la ejecución de uno o varios métodos de los controladores. Son clases derivadas de System.Web.Mvc.ActionFilterAttribute. A través de este mecanismo podemos añadir fácilmente funcionalidad a nuestros controladores evitando repetir la misma lógica una y otra vez, sobrescribiendo el comportamiento de algunas acciones.
image 
La plantilla incluye un filtro de ejemplo, InitializeSimpleMembership, en el siguiente ejemplo vemos como se utiliza el fitlro para decorar la clase AccountController (también incluida en la plantilla de proyecto)
[Authorize]
[InitializeSimpleMembership]
public class AccountController : Controller
{
    //
    // GET: /Account/Login

}
Veremos los filtros en profundidad mas adelante.

Directorio Images

Este es evidente … El directorio images es lugar para la imágenes de nuestra aplicación.
image
Como observación diremos que en el caso de que las imágenes formen parte del aspecto visual del sitio web, y no del contenido, deberían estar en el directorio content, como parte de un tema.
Por ejemplo, el contenido de una galería fotográfica o de un catalogo de productos debería estas en la carpeta images, mientras que las imágenes de fondo, iconos de los botones, sprites, etc deberían estar en la carpeta content junto con los archivos css. Básicamente, si una imagen se utiliza en un archivo css el lugar adecuado es la carpeta content.

Directorio Models

El directorio models es la ubicación que nos propone ASP.NET MVC para las clases que representan el modelo de la aplicación, los datos que gestiona nuestra aplicación.
image
Nota. En aplicaciones complejas, divididas en capas las clases de modelo suelen incluirse en assemblie aparte.
La siguiente clase muestra un ejemplo muy básico para representar el modelo de nuestra aplicación.
public class FooModel
{
    public Guid Id { get; set; }

    public string Name { get; set; }
}
Una de las grandes ventajas de las que disponemos en ASP.NET es que podemos decorar la clase que representa la modelo con diferentes atributos, que nos van a permitir establecer reglar sobre los datos como por ejemplo las reglas de la validación, si el datos es requerido o no, la longitud máxima y mínima del dato … etc
public class FooModel
{
    [Required]   
    public Guid Id { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 3)]    
    [Display(Name = "Name for FooModel")]
    public string Name { get; set; }
}
Como veremos cuando veamos las vistas, estos atributos son interpretados por la vista para establecer automáticamente las validaciones necesarias en función del los decoradores utilizados en el modelo.

Directorio Scripts

El directorio scripts está pensado para ubicar los archivos de javascript (*.js). El código javascript es ejecutado en el contexto del navegador, es decir, en la parte cliente, y nos permite ejecutar acciones sin necesidad de enviar los datos al servidor.
image
ASP.NET MVC incluye varias librerias de javascript por defecto:
  • jquery.js. Esta popular y súper útil librería nos va a permitir gestionar fácilmente peticiones AJAX, manipular el DOM en cliente, etc … Esta librería se ha convertido en un framework muy popular, y es la base de para la creación de pluggins que nos van a permitir dotar a nuestro sitio web de efecto sorprendentes sin apenas esfuerzo. http://jquery.com/
  • jquery.spin.js. Este pluggin nos permite crear animaciones de indicación de carga de contenidos el circulito que da vueltas para indicarnos que la página esta realizando algún proceso . Es un pluggin de jQuery basado en spin.js. http://fgnass.github.io/spin.js/
  • jquery.validate.js. Este pluggin nos permite realizar validaciones en el lado cliente fácilmente. Esta vinculado al uso de decoradores en el modelo de nuestra aplicación.
  • knockout.js. Esta librería nos permite utilizar el patrón de diseño MVVM (Model View ViewModel), que introdujo Microsoft para el desarrollo con WPF y Silverlight en aplicaciones web con javascript. http://knockoutjs.com/
  • modernizr.js. Esta librería nos permite validar fácilmente si el navegador que esta ejecutando la página web es compatible con HTML5, en en caso de que no sea así proporcional un mecanismo alternativo (polyfill). http://modernizr.com/. Por ejemplo, si nuestro navegador es compatible con HTML5 interpretará sin problema la etiqueta VIDEO, pero en el caso de que estemos navegando con un navegador antiguo deberemos ofrecer al usuario un mecanismo alternativo para el video (un flash por ejemplo). En el siguiente enlace podemos encontrar polyfills para casi todas las características de HTML5: https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
Nota: El nombre de los archivos puede varias dependiendo de la versión instalada, por ejemplo el archivo jQuery.js se llama jquery-1.7.1.js, ya que corresponde con la versión 1.7.1 de la librería.

Directorio Views

El directorios Views contiene los archivos de vista. Como explicamos en la introducción al patrón MVC los controladores devuelven vistas sobre las que inyectamos el modelo de nuestra aplicación. Estas vistas son interpretadas por el motor de renderización – Razor en nuestro caso. Son archivos similares a aplicaciones de ASP clasico, donde tenemos código HTML estático y determinadas zonas de código que son ejecutadas en el servidor.
image
El siguiente ejemplo muestra el clásico “Hola Mundo”.
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "HelloWorld";
}
<h2>HelloWorld</h2>
@*El código se servidor se especifica con el caracter @*@
Podemos asignar un modelo a la vista a través de la siguiente directiva.
@model MvcApplication1.Models.FooModel
Veremos las vistas en profundidad mas adelante.

Directorio Shared

El directorio Shared contiene vistas que van a ser reutilizadas en otras vistas. Veremos como incluir vistas - denominadas parciales – en otra vista cuando veamos Razor, aunque de manera muy breve diremos que se realiza a través del Helper Html, de la siguiente forma:
@Html.Partial("Error") @*Incluye la vista parcial Error.cshtml, del directorio Shared*@
En este caso es muy importante respetar la ubicación de los archivos, ya que cuando desde una vista hagamos la llamada @Html.Partial(“Error”) para incluir la vista de la pantalla de error, el motor buscara en el directorio Shared para encontrar la vista Error.cshtml.
No debemos confundir una vista compartida con los controles .ascx de ASP.NET WebForms. Cuando incluimos vistas compartidas en otra vista, esta son interpretadas por RAZOR sin ejecutarse ningún controlador. Simplemente se renderiza su contenido – no como en los controles ascx donde se ejecuta todo el ciclo de vida del control completo y sus correspondientes eventos.
Es posible utilizar una vistas compartida de un modo muy similar al de un control ascx de ASP.NET WebForms, aunque para este debemos forzar la ejecución del controlador a través de los métodos Action y RenderAction del Helper Html:
@Html.Action("About") @*Ejecuta el método "About" del controlador correspondiente*@

Archivo _ViewStart.cshtml

Este archivo establece el layout por defecto de las páginas. El contenido del archivo es sencillo y únicamente especifica el archivo de layout.
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
El layout es un archivo con extension .cshtml que contiene la estructura general de documento, que es reutilizada en el resto de vistas. De este modo evitamos tener que reescribir el código en todas las vistas, reutilizando el código y permitiendo que este sea mucho mas sencillo de mantener.
En cierto modo es similar a las MasterPages de ASP.NET WebForms.

Archivo _Layout.cshtml

El archivo _Layout.cshtml define el  layout de la aplicación, que contiene la estructura general de documento, que es reutilizada en el resto de vistas. El archivo _Layout.cshtml se encuentra dentro del directorio Views/Shared. El contenido del archivo layout por defecto se muestra a continuación:
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
        
    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
                </div>
                <div class="float-right">
                    <section id="login">
                        @Html.Partial("_LoginPartial")
                    </section>
                    <nav>
                        <ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
                </div>
            </div>
        </footer>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>
Fijemonos en la llamada que hace Razor al método @RenderBody(), es ahí donde se procesará la vista que estemos mostrando.
Podemos tener múltiples archivos de layout dentro de nuestro proyecto.

El archivo web.config

El archivo web.config es el archivo principal de configuración de ASP.NET. Se trata de un archivo XML donde se define la configuración de la aplicación. Veremos poco a poco el contenido de este fichero, aunque vamos a ver aquí algunas características generales que es necesario conocer.
image
Para simplificar el despliegue de las aplicaciones, el archivo de configuración se presenta en diferentes versiones o “sabores”, de forma que podemos modificar el archivo de configuración dependiendo de nuestra configuración de despliegue. Si observamos estos archivos observaremos que contienen transformaciones XML que se aplican sobre el archivo web.config al desplegar la aplicación. De este modo cuando desplegamos la aplicación en modo Debug se aplicarán las transformaciones XML definidas en Web.Debug.config.
El archivo de configuración aplica un mecanismo de jerarquía a nivel de los archivos de configuración, en la que un archivo de mayor profundidad dentro de la jerarquía sobrescribe al de menor, en el contexto del recurso solicitado.
image
Por ejemplo, si dentro de nuestra aplicación tenemos un archivo web.config sobre la raíz del sitio (en gris sobre la imagen), y otro sobre la carpeta Views (en rojo), el archivo de configuración de la carpeta Views prevalece y sobrescribe el valor del archivo de configuración raiz (siempre que el recurso solicitado sea se encuentre el directorio, en este ejemplo Views).
De esta forma podemos por ejemplo establecer en nuestro sitio web “areas” públicas y privadas de manera muy sencilla, tan fácil separar los archivo es directorios e como incluir un archivo de configuración con la seguridad activada sobre el directorio privado, y otro accesible a todo el mundo en el directorio privado. Veremos como hacer esto con Areas de ASP.NET un poquito mas adelante.

El archivo global.asax

Toda aplicación ASP.NET MVC es una instancia de una clase derivada de System.Web.HttpApplication. Esta clase es el punto de entrada de nuestra aplicación – el Main de la aplicación web por decirlo de alguna manera. Como podemos observar, la clase base es la misma que para una aplicación ASP.NET clásica (WebForms) por lo que todos que podemos reutilizar todo lo que ya sabíamos de ASP.NET.
Desde este archivo podemos manejar eventos a nivel de aplicación, sesión, cache, autenticacion,  etc ...
Este archivo varia mucho desde la versión anterior de ASP.NET MVC, aunque el funcionamiento es el mismo. En ASP.NET MVC 4 se ha incluido el directorio App_Start que nos permite organizar como se inicializa la aplicación.
// Por defecto, el namespace corresponde con el nombre del proyecto 
namespace MvcApplication1 
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }
}
Como podemos ver, el código se encarga de registrar las áreas definidas en el proyecto, cargar la configuración, filtros, etc…, en definitiva, se encarga de configurar la aplicación para que esta pueda ejecutar de manera correcta. Las clases de configuración se encuentran en el directorio App_Start
En el siguiente enlace podemos encontrar la documentación oficial sobre el archivo global.asax http://msdn.microsoft.com/en-us/library/1xaas8a2(v=vs.71).aspx
La lista completa de eventos disponibles es la siguiente:
// Summary:
//     Occurs when ASP.NET acquires the current state (for example, session state)
//     that is associated with the current request.
public event EventHandler AcquireRequestState;
//
// Summary:
//     Occurs when a security module has established the identity of the user.
public event EventHandler AuthenticateRequest;
//
// Summary:
//     Occurs when a security module has verified user authorization.
public event EventHandler AuthorizeRequest;
//
// Summary:
//     Occurs as the first event in the HTTP pipeline chain of execution when ASP.NET
//     responds to a request.
public event EventHandler BeginRequest;
//
// Summary:
//     Occurs when the application is disposed.
public event EventHandler Disposed;
//
// Summary:
//     Occurs as the last event in the HTTP pipeline chain of execution when ASP.NET
//     responds to a request.
public event EventHandler EndRequest;
//
// Summary:
//     Occurs when an unhandled exception is thrown.
public event EventHandler Error;
//
// Summary:
//     Occurs just before ASP.NET performs any logging for the current request.
public event EventHandler LogRequest;
//
// Summary:
//     Occurs when the handler is selected to respond to the request.
public event EventHandler MapRequestHandler;
//
// Summary:
//     Occurs when the request state (for example, session state) that is associated
//     with the current request has been obtained.
public event EventHandler PostAcquireRequestState;
//
// Summary:
//     Occurs when a security module has established the identity of the user.
public event EventHandler PostAuthenticateRequest;
//
// Summary:
//     Occurs when the user for the current request has been authorized.
public event EventHandler PostAuthorizeRequest;
//
// Summary:
//     Occurs when ASP.NET has completed processing all the event handlers for the
//     System.Web.HttpApplication.LogRequest event.
public event EventHandler PostLogRequest;
//
// Summary:
//     Occurs when ASP.NET has mapped the current request to the appropriate event
//     handler.
public event EventHandler PostMapRequestHandler;
//
// Summary:
//     Occurs when ASP.NET has completed executing all request event handlers and
//     the request state data has been stored.
public event EventHandler PostReleaseRequestState;
//
// Summary:
//     Occurs when the ASP.NET event handler (for example, a page or an XML Web
//     service) finishes execution.
public event EventHandler PostRequestHandlerExecute;
//
// Summary:
//     Occurs when ASP.NET bypasses execution of the current event handler and allows
//     a caching module to serve a request from the cache.
public event EventHandler PostResolveRequestCache;
//
// Summary:
//     Occurs when ASP.NET finishes updating caching modules and storing responses
//     that are used to serve subsequent requests from the cache.
public event EventHandler PostUpdateRequestCache;
//
// Summary:
//     Occurs just before ASP.NET starts executing an event handler (for example,
//     a page or an XML Web service).
public event EventHandler PreRequestHandlerExecute;
//
// Summary:
//     Occurs just before ASP.NET sends content to the client.
public event EventHandler PreSendRequestContent;
//
// Summary:
//     Occurs just before ASP.NET sends HTTP headers to the client.
public event EventHandler PreSendRequestHeaders;
//
// Summary:
//     Occurs after ASP.NET finishes executing all request event handlers. This
//     event causes state modules to save the current state data.
public event EventHandler ReleaseRequestState;
//
// Summary:
//     Occurs when the managed objects that are associated with the request have
//     been released.
public event EventHandler RequestCompleted;
//
// Summary:
//     Occurs when ASP.NET finishes an authorization event to let the caching modules
//     serve requests from the cache, bypassing execution of the event handler (for
//     example, a page or an XML Web service).
public event EventHandler ResolveRequestCache;
//
// Summary:
//     Occurs when ASP.NET finishes executing an event handler in order to let caching
//     modules store responses that will be used to serve subsequent requests from
//     the cache.
public event EventHandler UpdateRequestCache;

Home Controller

La clase HomeController es el punto de entrada de la aplicación, la página por defecto.
Cuando creamos un nuevo proyecto ASP.NET MVC se crea también un controlador HomeController situado directamente el folder Controllers
image
El controlador de ejemplo que se incluye en el proyecto por defecto, incluye tres métodos: Index, About y Contact, que disponen de sus correspondiente vistas en el folder Home.
image
El código del HomeController es el siguiente:
namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your app description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}
Como podemos ver cada uno de los métodos del controlador devuelve la vista asociada por defecto:
  • Index() devuelve la vista index.cshtml
  • About() devuelve la vista about.cshtml
  • Contact() devuelve la vista contact.cshtml
Veremos los controladores en el siguiente capitulo.

Creación de Áreas.

Como hemos visto, ASP.NET MVC divide los elementos que componen su arquitectura en carpetas con el mismo nombre (Models, Views, Controllers). Esta división es fácil e intuitiva pero puede ser limitada en aplicaciones grandes, donde el número de entidades a manejar sea grande. Para estos casos ASP.NET MVC proporciona un mecanismo muy sencillo que nos permite agrupar contenidos (y sus configuraciones) denominadas Areas.
Un Area no es mas que una carpeta que replica en su interior la estructura anterior de MVC - Model, Views, Controllers y define sus propias rutas de acceso a través de la clase PublicContentAreaRegistration que se crea automáticamente al añadir una nueva área. Tiene la ventaja adicional de tener su propio archivo de configuración de modo que es ideal para diferenciar zonas públicas y privadas por ejemplo.
Podemos crear Areas del siguiente modo:
Sobre el explorador de soluciones de Visual Studio,
image
Visual Studio nos preguntara el nombre del área que queremos crear, en nuestro caso le damos el nombre PublicContent
image
Podemos ver que se ha creado en Visual Studio un directorio Areas, con un subdirectorio PublicContent en el que podemos encontrar la estructura de carpetas de Controllers, Models y Views que ya hemos visto anteriormente.
image
También tenemos un archivo de configuración (que nos permite sobrescribir la configuración raiz a través del mecanismo de jerarquia explicado anteriormente) y un archivo PublicContentAreaRegistration.cs en el que se registra la ruta del área sobre la tabla de rutas de ASP.NET MVC (veremos como funciona este mecanismo mas adelante), de momento diremos que la tabla de ruta establece un mapeo entre las URLs que envía el navegador y el controlador que debe gestionar estas peticiones.

Fuente: http://www.devjoker.com/
Si te ha parecido interesante podrías hacer click en +1, compartirlo en Facebook o Twitter, o dejar un comentario. ¡Gracias!.

No hay comentarios.:

Publicar un comentario