ASP.NET MVC. Personalizar el Motor de Vistas de MVC (I). Creando el escenario.
ASP.NET MVC. Personalizar el Motor de Vistas de MVC (II). Comprendiendo las vistas de MVC.
En los anteriores artículos creamos un escenario en el que generábamos vistas en un formato xml personalizado y tratamos de comprender la forma en que el Framework de ASP.NET MVC gestiona las vistas.
En este artículo mostraré cómo crear y registrar el motor de vistas para gestionar estas vistas en formato xml.
Como vimos en el anterior artículo el resultado generado por el motor de vistas debe ser un objeto que implemente la interfaz IView. Así que lo primero que voy a hacer es crear una clase que implemente esta interfaz y que utilizaremos para generar el resultado de nuestro motor. He creado una nueva clase ScreenView en una carpeta Infrastructure dentro del proyecto.
He creado la clase de forma que el constructor reciba el nombre de la vista a generar. De esta forma sabremos a partir de qué archivo xml debemos crear el formulario.
Por el momento la vista simplemente envía como salida el nombre de la vista a mostrar. Esto nos servirá para comprobar que el motor de vistas ha respondido a la petición de la vista de forma correcta. En el siguiente artículo modificaremos esta clase ScreenView para generar el código HTML que mostrará el formulario definido en el archivo xml.
Para crear el motor de vistas voy a crear una clase ScreenViewEngine en la carpeta Infrastructure. Como vimos anteriormente el motor debe implementar la interfaz IViewEngine.
He establecido como convención que las vistas que gestiona el motor de vistas ScreenViewEngine tendrán un nombre prefijado por screen_. De esta forma evitaremos problemas en caso de que se definan con el mismo nombre vistas para Razor y para nuestro motor de vistas. Cada motor podrá identificar qué vistas le corresponden.
Como ya comenté, la clase ViewEngineResult dispone de dos constructores y se debe usar uno u otro en función de si el motor de vistas es capaz de gestionar la vista solicitada. Así que en el método FindPartialView compruebo si el nombre de la vista tiene el prefijo screen_ y, si no es así, utilizo el contructor de ViewEngineResult que recibe una colección de Strings para indicar que el motor no puede gestionar la vista solicitada.
Si el prefijo coincide, obtengo el nombre real de la vista (sin prefijo) y compruebo si existe un archivo xml en la carpeta Screens con ese nombre. Si no existe el archivo devuelvo un objeto ViewEngineResult indicándole la ruta en la que el motor ha intentado localizar la vista.
Si el archivo existe, significa que el motor de vistas es capaz de gestionar la solicitud y devuelve la vista como una nueva instancia de la clase ScreenView. El Framework de MVC se encargará de llamar al método Render de la vista para generar la salida a enviar al navegador.
Como comentamos, vamos a tratar siempre las vistas xml como vistas parciales por lo que el método FindView devuelve directamente un texto indicando que no puede gestionar la solicitud, independientemente de la vista solicitada.
De esta forma ya hemos creado el motor de vistas, sin embargo aún queda un último paso quedar: registrarlo o, lo que es lo mismo, crear una instancia del motor e indicarle al Framework de MVC que debe utilizar este motor para gestionar las vistas de la aplicación. Este registro lo realizaremos en el método Application_Start del archivo Global.asax de la aplicación:
La colección ViewEngines.Engines contiene todos los motores de vistas utilizados por la aplicación. Cuando se genera una solicitud para mostrar una vista (o una vista parcial), MVC llama al método FindView (o FindPartialView) de cada motor de vistas. En el momento que un motor de vistas devuelve una instancia de IView en el objeto ViewEngineResult el MVC procesa la vista sin llamar al resto de motores.
Para probar el motor nos falta realizar un último cambio: modificar la vista Index para que llame a la vista parcial.
Como se puede observar he añadido el prefijo screen_ al nombre de la vista para que sea gestionada por el nuevo motor de vistas. Mediante el método Html.RenderPartial invoco a la vista parcial pasándole el nombre de ésta y el modelo con la información a mostrar en el formulario.
Si ahora navegamos a las rutas /Home/Index/PersonaSimple y /Home/Index/PersonaCompleto obtendremos el mismo resultado que antes, aunque ahora el nombre de la vista lo proporciona el motor de vistas ScreenViewEngine en lugar de escribirlo directamente en la vista Index.
El resultado es más interesante si tratamos de mostrar una vista que no existe. Por ejemplo si introducimos la url /Home/Index/OtroFormulario.
Como era de esperar la aplicación devuelve un error y, en la información del error, aparece el listado de ubicaciones donde el motor de vistas Razor a tratado de encontrar la vista a mostrar. Sin embargo a continuación aparece algo importante: la ruta en la que el motor ScreenViewEngine a tratado de encontrar la vista a mostrar (~/Screens/OtroFormulario.xml). Ésta es la cadena que pasábamos como resultado en el objeto ViewEngineResult cuando no existía el archivo xml:
Ya tenemos registrado y funcionando el motor de vistas personalizado. Sin embargo el objetivo inicial parece seguir estando lejos: "mostrar los formularios diseñados a través de una herramienta externa en un formato propio dentro de nuestra aplicación MVC".
Pero no es así. Realmente estamos muy cerca de acabar nuestro trabajo como veremos en el próximo artículo:
El código completo de este artículo y los otros tres de la serie, tanto en C# como en Visual Basic, está disponible en:
Crear un motor de vistas personalizado en ASP.NET MVC. - Ejemplos MSDN.
Crear un motor de vistas personalizado en ASP.NET MVC. - Ejemplos MSDN.
No hay comentarios:
Publicar un comentario