miércoles, 6 de mayo de 2015

ASP.NET MVC. Personalizar el Motor de Vistas (View Engine) de MVC (II). Comprendiendo las vistas de MVC.

Este artículo es continuación de:
ASP.NET MVC. Personalizar el Motor de Vistas de MVC (I). Creando el escenario.

En el anterior artículo creamos un escenario con un formato de vistas xml en el que nos resultaría útil crear un motor de vistas personalizado. En este artículo voy a mostrar cómo crear y registrar el motor de vistas que generará las páginas de la aplicación a partir del formato de vistas personalizado.

Los motores de vista de ASP.NET MVC deben implementar la interfaz IViewEngine.

namespace System.Web.Mvc
{
    public interface IViewEngine
    {
        ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
        ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
        void ReleaseView(ControllerContext controllerContext, IView view);
    }
}

Los métodos FindPartialView y FindView se llaman cuando MVC trata de procesar una vista y reciben como parámetros un objecto ControllerContext con la información de la petición, el nombre de la vista a mostrar y un valor booleano que indica si el motor puede reutilizar resultados anteriores desde la caché. Ambos métodos devuelven un objeto ViewEngineResult que sirve para comunicar al Framework MVC el resultado de la solicitud de la vista.

El último método, ReleaseView, es llamado por MVC cuando no necesita más la vista, y será el responsable de liberar cualquier recurso utilizado por ésta.

La clase ViewEngineResult es un poco especial:

using System.Collections.Generic;

namespace System.Web.Mvc
{
    public class ViewEngineResult
    {
        public ViewEngineResult(IEnumerable<string> searchedLocations)
        {
            if (searchedLocations == null)
            {
                throw new ArgumentNullException("searchedLocations");
            }

            SearchedLocations = searchedLocations;
        }

        public ViewEngineResult(IView view, IViewEngine viewEngine)
        {
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }
            if (viewEngine == null)
            {
                throw new ArgumentNullException("viewEngine");
            }

            View = view;
            ViewEngine = viewEngine;
        }

        public IEnumerable<string> SearchedLocations { get; private set; }

        public IView View { get; private set; }

        public IViewEngine ViewEngine { get; private set; }
    }
}



Cómo decía es bastante especial. Tiene una implementación bastante extraña que no encaja con el diseño del resto de clases del Framework.

Esta clase permite definir dos tipos de resultados distintos:

  • Cuando el motor de vistas no es capaz de devolver una vista para la petición devuelve una colección de stings a través de la propiedad SearchedLocations en la que indica las rutas examinadas para tratar de localizar la vista.
  • Si el motor de vistas es capaz de devolver una vista para la petición devuelve una referencia a la vista (a través de la propiedad View) y al motor de vistas (a través de la propiedad ViewEngine)
Dependiendo del resultado que se desee devolver se debe utilizar un constructor diferente.

Si no te gusta la forma en que está implementada esta clase te puedo asegurar que no eres el único.

Cuando el motor de vistas devuelve una vista como respuesta a la petición a través de la propiedad View del objeto ViewResult, debe devolver un objeto que implemente la interfaz IView.

using System.IO;

namespace System.Web.Mvc
{
    public interface IView
    {
        void Render(ViewContext viewContext, TextWriter writer);
    }
}

La interfaz es muy simple. Únicamente proporciona un método Render que será invocado por el Framework MVC para generar la salida a enviar al cliente.

Este método recibe dos parámetros. Un objeto ViewContext con la información de la petición realizada por el cliente y un objeto TextWriter que permite escribir la salida a enviar al cliente.

En los siguientes artículos veremos cómo utilizar esta arquitectura para implementar un nuevo motor de vistas:

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.

No hay comentarios:

Publicar un comentario