Razor View Engine para ASP.NET MVC 3

 

 
Una de las novedades con mejor acogida de la nueva versión del frameworkd ASP.NET MVC 3 ha sido sin duda el nuevo motor de vistas llamado Razor. Si bien es cierto que con las primeras versiones y el motor de vistas aspx muchos programadores se echaban para atrás con ASP.NET MVC, con Razor podremos generar vistas de una forma más sencilla y fluida. En este post voy a comentar algunas de las diferencias y mejoras respecto al anterior view engine predeterminado.

 

En primer lugar, Razor pasa a ser el motor de vistas por defecto, aunque tenemos disponibles ambos al crear un nuevo proyecto o una nueva vista.
 

 

Accediendo a variables de servidor

Si recordáis, cuando trabajamos con el aspx view engine, para acceder al contenido de Model, ViewData, helpers, etcétera necesitábamos añadir las siguientes etiquetas: <%: %>
<p>Please enter your username and password. <%: Html.ActionLink("Register", "Register") %>
if you don't have an account.</p>
Con Razor simplemente utilizaremos @ al inicio y el view engine se encargará de determinar hasta dónde debe procesar.
<p>Please enter your username and password. @Html.ActionLink("Register", "Register") if
you don't have an account.</p>

Recorrer una lista

Para recorrer una lista es bastante similar a como lo haríamos con el motor aspx, con la diferencia del etiquetado para comenzar la sentencia foreach.
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
        <td>
            @item.FirstName
        </td>
        <td>
            @item.LastName
        </td>
        <td>
            @item.Address
        </td>
        <td>
            @item.E_Mail
        </td>
        <td>
            @item.Mobile
        </td>
    </tr>
}
Si nos fijamos en la llave de cierre del bucle, vemos que en Razor no es necesario etiquetar esa llave :D ya que se supone que pertenece a la llave de apertura abierta anteriormente, caso que no ocurría con aspx view engine:
<% foreach (var item in Model) { %>
    <tr>
        <td>
            <%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
            <%: Html.ActionLink("Details", "Details", new { id=item.Id }) %> |
            <%: Html.ActionLink("Delete", "Delete", new { id=item.Id }) %>
        </td>
        <td>
            <%: item.FirstName %>
        </td>
        <td>
            <%: item.LastName %>
        </td>
        <td>
            <%: item.Address %>
        </td>
        <td>
            <%: item.E_Mail %>
        </td>
        <td>
            <%: item.Mobile %>
        </td>
    </tr>
<% } %>

Bloques de código

Por otro lado, para utilizar bloques de código bastará con utilizar la arroba y abrir llaves para delimitar el espacio abarcado por el bloque.
@{
    ViewBag.Title = "Loop";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Tag <text>

Otro escenario que se nos puede presentar es que dentro de un bloque de código necesitemos añadir código javascript o HTML que no requiera ser procesado por el motor.
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
        http://asp.net/mvc</a>.
</p>
@if (DateTime.Now.Year == 2011)
{
    <text>while year is 2011 this should be shown.</text>
}
Para que nos hagamos una idea más clara, si no añadimos el tag <text>, algunas partes del código anterior sería interpretadas como palabras clave.

Archivo _ViewStart.cshtml

Para conseguir unas vistas más limpias y concisas, aparece un nuevo archivo llamado _ViewStart.cshtml.
 
El objetivo del mismo trata de recopilar código común a todas las vistas de la aplicación, simplificando el código de las mismas. Por defecto aparece definido en él el layout utilizado en las vistas, en caso de no ser especificado en las mismas.
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Sections 

Otra de las novedades dentro de Razor es la posibilidad de crear secciones.
<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
</head>
<body>
    <div>
        <div id="header">
            <div id="title">
                <h1>
                    My MVC Application</h1>
            </div>
            <div id="logindisplay">
                @Html.Partial("_LogOnPartial")
            </div>
            <div id="menucontainer">
                <ul id="menu">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                </ul>
            </div>
        </div>
        <div id="main">
            @RenderBody()
            <div id="footer">
                @RenderSection("returngis");
            </div>
        </div>
    </div>
</body>
</html>
 Cuando definimos una sección en el layout, el objetivo principal es que la misma pueda ser modificada dinámicamente dependiendo de la vista que solicitemos de la siguiente manera.
@section returngis{
    <p>Este es un ejemplo para <a href="http://www.returngis.net">Returng(GiS);</a></p>
}
Si tenemos varias vistas dependiendo del anterior layout y no todas asignan un valor a la sección definida anteriormente, al acceder a alguna de las vistas sin esta definición saltaría la siguiente excepción:
 
 
Este error ocurre debido a que, por defecto, cuando se define una sección se da por hecho que la misma debe estar implementada en cualquier vista que utilice este layout. Para evitar esto, basta con modificar la definición de la sección agregando el parámetro false al final para convertir la sección de obligatorio a opcional.
@RenderSection("returngis", false)

Nuevos helpers

Por último, y no por ello menos importante :D , se añaden a nuestra lista de helpers 5 más, algunos de ellos imprescindibles:

 

  • Chart: A partir de la versión 3 no necesitaremos crear un chart from scratch como hacíamos en este antiguo post. Este helper renderiza exactamente las mismas características que en ASP.NET 4.
  • WebGrid: Un helper más que necesario el cual renderiza un grid con paginación y ordenación. Gracias a José M. Aguilar tenemos un tutorial de este helper explicando paso a paso cada una de las funcionalidades.
  • Crypto: Utilizado para crear password hash.
  • WebImage: Se utiliza para renderizar imágenes.
  • WebMail: Nos ayuda en el envío de emails.
Espero que sea de utilidad :D
¡Saludos!  

4 comentarios en “Razor View Engine para ASP.NET MVC 3”

  1. Hola!

    Muy interesante el artículo 🙂

    Hay algo que me llama la atención de los posts sobre Razor, y es que en todos se empeñan en mostrar el uso de la @ como una ventaja. Es cierto que es más cómodo de utilizar, pero creo que para la mantenibilidad, el hecho de tener bien diferenciado lo que se va a procesar por parte del servidor de lo que es código ASP.NET o simplemente HTML es más una ventaja que un engorro…

    Debe ser que me hago viejo 😀

  2. @Augusto yo pensaba lo mismo, incluso me parecía una involución el mezclar cliente y servidor en el mismo archivo, la sensación de tener todo separado como se hacía en webforms te hacia separar lo engorroso de mezclar los lenguajes, pero cuando empiezas a usarlo sientes que te ayuda en el desarrollo.

    Es cuestión de romper el paradigma, Gisela gracias por el post.

  3. @Augusto
    La clave es que en MVC vas a tener poco código de servidor.
    Si tienes mucho, es debido a dos causas:
    1) O bien ese código es de presentación => Lo mueves a un helper

    2) O bien ese código NO es de presentación => Entonces estás usando mal MVC. 😉

    Un saludo!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *