lunes, 27 de abril de 2015

ASP.NET MVC. Obtener el código generado por una vista Razor cshtml/vbhtml

El motor de vistas de Razor traduce las vistas escritas en sintaxis Razor a clases con código en C# o VB.NET y a continuación las compila. Este es el motivo por el que resulta tan sencillo incluir fragmentos de código en C# o VB.NET en las vistas.

En ocasiones puede resultar útil analizar el código de estas clases, bien para localizar errores, bien para comprender cómo funcionan estas vistas. Sin embargo puede resultar complicado localizar los archivos en los que el motor de vistas Razor genera este código. Vamos a ver cómo podemos encontrarlos de manera sencilla.


Para mostrar cómo localizar los ficheros con el código fuente generado por Razor voy a utilizar el proyecto MVCDateTimePicker que creé en los artículos ASP.NET MVC. Platilla de editor para fecha y horaASP.NET MVC. Gestión de Scripts en Plantillas y Vistas Parciales y cuyo código puede descargarse desde ASP.NET MVC Editores Date y DateTime con helper para gestión de scripts.

En este proyecto existe una única vista Index.cshtml/Index.vbhtml muy simple que muestra un formulario para editar un objeto de la clase Persona.

@model MVCDateTimePicker.Models.Persona

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <br/>
    <input type="submit" value="Validar" />
}
@ModelType MVCDateTimePicker.Persona

@Using (Html.BeginForm())
    @Html.EditorForModel()
    @:<br />
    @:<input type="submit" value="Validar" />
End Using

El motor de vistas de Razor no genera el código correspondiente a las vistas hasta que debe visualizarlas por lo que es necesario arrancar la aplicación para que se generen. La ubicación utilizada para generar estos ficheros de código depende de diferentes variables (el servidor que utilicemos, el sistema operativo, ...). La forma más sencilla de localizar esta ubicación consiste en introducir un error en el código de la vista y obtener la ubicación de la información del error generado.

Voy a introducir una instrucción que genere un error de compilación en la vista Index:

@model MVCDateTimePicker.Models.Persona
@generarerror

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <br/>
    <input type="submit" value="Validar" />
}
@ModelType MVCDateTimePicker.Persona
@generarerror

@Using (Html.BeginForm())
    @Html.EditorForModel()
    @:<br />
    @:<input type="submit" value="Validar" />
End Using

Si tratamos de arrancar la aplicación evidentemente la instrucción generarerror provocará un error de compilación.


Pulsando en el link Mostrar el código fuente de la compilación completo vemos el código generado por Razor para la vista Index:




De esta forma podemos ver el código fuente generado por Razor pero seguimos sin tener la ubicación de los ficheros. Para ello deberemos hacer click sobre el otro link de la pantalla de error: Mostrar los resultados del compilador detallados:


Este link nos muestra la llamada al compilador ejecutada y el error generado por éste.

Podemos ver que el compilador recibe como parámetros las referencias a las dlls utilizadas y, al final, unos archivos cs o vb. En mi caso estos archivos son:
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\efdbbb24\2246f9b1\App_Web_index.cshtml.a8d08dba.wumw63bk.0.cs
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\efdbbb24\2246f9b1\App_Web_index.cshtml.a8d08dba.wumw63bk.1.cs
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\8b952dee\308ce0fc\App_Web_index.vbhtml.a8d08dba.eeodpfam.0.vb
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\8b952dee\308ce0fc\App_Web_index.vbhtml.a8d08dba.eeodpfam.1.vb
De esta forma podemos ver la carpeta en la que Razor está generando los archivos con el código fuente. De hecho, si abrimos el primero de los ficheros, podremos ver el código fuente generado para la vista Index.

#pragma checksum "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "B920555B8F31320BC5C74B229061BF8627C029E2"
//------------------------------------------------------------------------------
// <auto-generated>
//     Este código fue generado por una herramienta.
//     Versión de runtime:4.0.30319.0
//
//     Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
//     se vuelve a generar el código.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ASP {
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.WebPages;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    using MVCDateTimePicker;
    
    
    public class _Page_Views_Home_Index_cshtml : System.Web.Mvc.WebViewPage<MVCDateTimePicker.Models.Persona> {
        
#line hidden
        
        public _Page_Views_Home_Index_cshtml() {
        }
        
        protected ASP.global_asax ApplicationInstance {
            get {
                return ((ASP.global_asax)(Context.ApplicationInstance));
            }
        }
        
        public override void Execute() {
BeginContext("~/Views/Home/Index.cshtml", 42, 12, false);

            
            #line 2 "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml"
Write(generarerror);

            
            #line default
            #line hidden
EndContext("~/Views/Home/Index.cshtml", 42, 12, false);

BeginContext("~/Views/Home/Index.cshtml", 54, 4, true);

WriteLiteral("\r\n\r\n");

EndContext("~/Views/Home/Index.cshtml", 54, 4, true);

            
            #line 4 "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml"
 using (Html.BeginForm())
{
    
            
            #line default
            #line hidden
BeginContext("~/Views/Home/Index.cshtml", 93, 21, false);

            
            #line 6 "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml"
Write(Html.EditorForModel());

            
            #line default
            #line hidden
EndContext("~/Views/Home/Index.cshtml", 93, 21, false);

            
            #line 6 "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml"
                          

            
            #line default
            #line hidden
BeginContext("~/Views/Home/Index.cshtml", 116, 11, true);

WriteLiteral("    <br/>\r\n");

EndContext("~/Views/Home/Index.cshtml", 116, 11, true);

BeginContext("~/Views/Home/Index.cshtml", 127, 10, true);

WriteLiteral("    <input");

EndContext("~/Views/Home/Index.cshtml", 127, 10, true);

BeginContext("~/Views/Home/Index.cshtml", 137, 14, true);

WriteLiteral(" type=\"submit\"");

EndContext("~/Views/Home/Index.cshtml", 137, 14, true);

BeginContext("~/Views/Home/Index.cshtml", 151, 16, true);

WriteLiteral(" value=\"Validar\"");

EndContext("~/Views/Home/Index.cshtml", 151, 16, true);

BeginContext("~/Views/Home/Index.cshtml", 167, 5, true);

WriteLiteral(" />\r\n");

EndContext("~/Views/Home/Index.cshtml", 167, 5, true);

            
            #line 9 "E:\Desarrollo\Blog\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.cshtml"
}
            
            #line default
            #line hidden
        }
    }
}
#ExternalChecksum("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml","{ff1816ec-aa5e-4d10-87f7-6f4963833460}","F4A95AFE49D6BB2264938D81952F5847F58DD498")
'------------------------------------------------------------------------------
' <auto-generated>
'     Este código fue generado por una herramienta.
'     Versión de runtime:4.0.30319.0
'
'     Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
'     se vuelve a generar el código.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On

Imports MVCDateTimePicker
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Net
Imports System.Web
Imports System.Web.Helpers
Imports System.Web.Mvc
Imports System.Web.Mvc.Ajax
Imports System.Web.Mvc.Html
Imports System.Web.Routing
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.WebPages

Namespace ASP
    
    Public Class _Page_Views_Home_Index_vbhtml
        Inherits System.Web.Mvc.WebViewPage(Of MVCDateTimePicker.Persona)
        
        Public Sub New()
            MyBase.New
        End Sub
        
        Protected ReadOnly Property ApplicationInstance() As ASP.global_asax
            Get
                Return CType(Context.ApplicationInstance,ASP.global_asax)
            End Get
        End Property
        
        Public Overrides Sub Execute()
BeginContext("~/Views/Home/Index.vbhtml", 39, 12, false)

            
            #ExternalSource("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml",2)
Write(generarerror)

            
            #End ExternalSource
EndContext("~/Views/Home/Index.vbhtml", 39, 12, false)

BeginContext("~/Views/Home/Index.vbhtml", 51, 4, true)

WriteLiteral(""&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10)&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10))

EndContext("~/Views/Home/Index.vbhtml", 51, 4, true)

            
            #ExternalSource("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml",4)
 Using (Html.BeginForm())
    Dim p As Integer = CType("pepito", Integer)
    
            
            #End ExternalSource
BeginContext("~/Views/Home/Index.vbhtml", 136, 21, false)

            
            #ExternalSource("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml",6)
Write(Html.EditorForModel())

            
            #End ExternalSource
EndContext("~/Views/Home/Index.vbhtml", 136, 21, false)

            
            #ExternalSource("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml",6)
                          

            
            #End ExternalSource
BeginContext("~/Views/Home/Index.vbhtml", 159, 4, true)

WriteLiteral("    ")

EndContext("~/Views/Home/Index.vbhtml", 159, 4, true)

BeginContext("~/Views/Home/Index.vbhtml", 165, 8, true)

WriteLiteral("<br />"&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10))

EndContext("~/Views/Home/Index.vbhtml", 165, 8, true)

BeginContext("~/Views/Home/Index.vbhtml", 173, 4, true)

WriteLiteral("    ")

EndContext("~/Views/Home/Index.vbhtml", 173, 4, true)

BeginContext("~/Views/Home/Index.vbhtml", 179, 41, true)

WriteLiteral("<input type=""submit"" value=""Validar"" />"&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10))

EndContext("~/Views/Home/Index.vbhtml", 179, 41, true)

            
            #ExternalSource("E:\Desarrollo\Blog\VB\MVCDateTimePicker\MVCDateTimePicker\Views\Home\Index.vbhtml",9)
End Using
            
            #End ExternalSource
        End Sub
    End Class
End Namespace



No hay comentarios:

Publicar un comentario