[ASPNET] Enrutamiento en Webform. Tener url mas amigables utilizando restricciones, creando enlaces (Codebehind y expresiones en modo diseño)

Como en el anterior post de esta temática sobre utilizar el modulo de IIS Url Rewrite… Aquí dejo las alternativas pero ya utilizando el enrutamiento mediante los Routes, que los que trabajamos con ASP.NET MVC ya estamos acostumbrados  y que tenemos desde la versión de ASP.NET 4.0 para Webforms (pero que venia ya en el SP1 de NET 3.5). Aquí dejo la introducción de utilizarlos con nuestros queridos Webforms.

Nos ayudaremos de esta configuración de enrutamiento para darle forma a los Request “enrutadas” que aceptaremos (las url) y como obtener los parámetros que vienen en dichas url (ya sea por codebehind, expresion en modo diseño o en un dataBinding) como asi también como escribir las url enrutadas vía código.

 

¿Que necesitamos mapear?

Lo que se requiere es poder mapear por ejemplo esta URL (un poco extensa)

http://localhost/PruebaLandingVuelo.aspx?promocion=santiago-scl-buenosaires-bue-01_10_2013-05_12_2013

A algo mucho mas amigable

http://localhost/vuelo/santiago-scl/buenosaires-bue/01_10_2013/05_12_2013

O sea lo que queremos hacer es direccionar la petición (request) a un archivo que no existe físicamente! o sea no se tiene el archivo físico que controla el request…. es decir nuestro querido webform (ni handler)!

 

Tenemos algunas alternativas (para incluso para Webforms…)

  1. El modulo del IIS Url Rewrite
    Muy fácil y transparente para la app web… cualquiera sea no necesariamente ASP.NET
    http://www.iis.net/downloads/microsoft/url-rewrite
    Que ya escribí el anterior post:
  2. También existen la posibilidad de redireccionar mediante HttpContext.RewritePath
    (lo bueno que lo tenemos desde la versión de ASP.NET 2.0)
    http://msdn.microsoft.com/es-es/library/system.web.httpcontext.rewritepath.aspx
  3. Pero desde la versión de ASP.NET 4.0 tenemos el Enrutamiento/Routes (idem a los que utilizamos en MVC)
    Que es el tema del presente post..

 

 

¿Como lo hacemos en Webforms el Enrutamiento… las rutas?

Para eso tenemos que realizar estos pasos

  1. Agregando Rutas con RouteCollection.MapPageRoute
    • NOTA 1.1: Valores predeterminados en los parámetros de las rutas
    • NOTA 1.2: Números variables de segmentos en la url o enviar parámetros con el carácter / con el comodín *
    • NOTA 1.3: Restricciones a las rutas
  2. Recuperando valores de la pagina enrutada
    • Por Codebehind: Utilizando la propiedad Page.RouteData
    • En Modo diseño: Utilizando en las propiedades de los controles con la expresión RouteValue (Text="<%$RouteValue:nombre%>" )
    • En los controles que soportan el DataBinding, utilizando RouteParameter
  3. A tener en cuenta al momento de crear enlaces de url enrutadas! Crear hipervinculos
    • Creando el hipervínculo manualmente (lo que siempre nos tentamos a hacer)
    • Creando automáticamente en modo diseño: Dejando que ASP.NET genere la ruta que se ajustas a los paremetros pasados en la expresion RouteUrl
    • Creando desde codebehind: Utilizando RouteValueDictionary y el método RouteCollection.GetVirtualPath

 

PASO 1: Agregando Rutas con RouteCollection.MapPageRoute

Para agregar las rutas nos valemos del metodo RouteCollection.MapPageRoute que tiene esta forma

public Route MapPageRoute(
string routeName,
string routeUrl,
string physicalFile
)
Esto es conveniente hacerlo al inicio de la aplicación, o sea en el Global.asax en el método especial Application_Start . ¿Por qué allí? Para tenerlo disponible para cuando se inicia la aplicación, pero en cualquier momento podremos manipular esta colección, además de tenerlo disponible para las pruebas unitarias. Como veras tiene un key para acceder a una ruta en particular.
Se registran las rutas en RouteTables que contiene todas las rutas de nuestra app.
 
Ejemplo con la url que queremos reescribir, los parámetros para la ruta van entre {}
SNAGHTML108da4bd

(NOTA: Agrego el namespaces completo de RouteTables)

 

NOTA 1.1: Valores predeterminados en los parámetros de las rutas

Aquí ya tendremos que utilizar la sobrecarga del método MapPageRoute

public Route MapPageRoute(
string routeName,
string routeUrl,
string physicalFile,
bool checkPhysicalUrlAccess,
RouteValueDictionary defaults
)

Donde vemos que el ultimo parámetro RouteValueDictionary es un diccionario (par/valor) donde indicamos dichos valores por default.

En el ejemplo si queremos agregar un valor por default seria algo así:

SNAGHTML108f76db

En este ejemplo no es necesario los valores por default, solo a modo de ejemplificar.

 

NOTA 1.2: Números variables de segmentos en la url o enviar parámetros con el carácter / con el comodín *

A veces es conveniente tener varios parámetros adicionales (y no podremos escribir una ruta “dependiente de dichos parámetros”

Algo así

/vuelos/{promocion}/{param1}/…/{paramN}

Entonces la ruta la podrías escribir algo así

~/vuelos/{promocion}/{*param1}

Y allí cuando lo recuperamos vamos a tener los valores de esta manera

valor1/valor2/valor3

Por eso es útil para necesitamos que el parámetro reciba un path, url, o valor que contenga el carácter / (por lo menos es en el único lugar que lo utilice por ahora)

 

NOTA 1.3: Restricciones a las rutas

Podremos  a las rutas además definir restricciones para definir mucho mejor el mapeo, así no se mapeara si no satisface dicha restricción… y no tendremos que hacer validaciones en nuestro código. Así que es muy útil por ejemplo cuando esperamos solo números, un formato o valores especiales, etc.

Para eso hay una sobrecarga mas de este único método MapPageRoute que soporta dicho valor de restricción, que también es un diccionario RouteValueDictionary pero en cuyo valor va una expresión regular (esa cosa que solo entienden los vulcanos, pero que es simple y potente)

Vemos que tenemos una sobrecarga:

SNAGHTML14c0668c

Para el ejemplo que tenemos la url debe tener esta forma:

/vuelo/santiago-scl/buenosaires-bue/01_10_2013/05_12_2013

La expresión regular que soporta cada grupo de parámetros puede ser algo así:

  • origen y destino: [a-z]*-[a-z]{3}
  • fechas de salida y regreso: [0-9]{2}_[0-9]{2}_[0-9]{4}

NOTA: En el anterior post hay una expresión regular mas “exacta”. Dale una mirada…

Entonces nos quedaría la ruta con la restricción

SNAGHTML10941d85

 

A tener en cuenta

Este mapeo de ruta no funcionara…

  • Si el archivo físico se encuentra físicamente, no se mapeara la ruta.

    Salvo que se habilite la propiedad RouteExistingFiles
  • Si se deshabilita algunas rutas mediante la collecion  RouteCollection.Ignore

 

Paso 2: Recuperando valores de la pagina enrutada

Para obtener los valores de los parámetros

  • En el Codebehind…

    Dentro de nuestro codebehind tendremos que acceder a la propiedad Page.RouteData que tiene una colección de Values

    Ejemplo:

var promocion = Page.RouteData.Values["promocion"].ToString();

 
  • En modo diseño podemos enlazar directamente una propiedad al valor  mediante la expresión $RouteValue
<asp:Literal ID="litPromocionConExpresion" 
runat="server"
Text="<%$RouteValue:promocion%>" />

  • Y tenemos en los controles que soportan binding/enlace la posibilidad de enlazar directamente al valor RouteParameter

    Algo así

    ...
    <SelectParameters>
    <asp:RouteParameter DefaultValue="ValorPorDefault" Name="promocion" RouteKey="promocion" />
    </SelectParameters>
    ...

    Ejemplo mas completo aquí…

 

Paso 3: A tener en cuenta al momento de crear enlaces de url enrutadas! Crear hipervínculos

Aquí tienes dos opciones… o generamos la url manualmente (la que creamos en la ruta) o dejamos que ASP.NET genere por nosotros la ruta que se ajusta a los parámetros que pasamos. Veamos

  1. Generar un Hipervínculo manualmente (conociendo la ruta)

    <asp:HyperLink ID="HyperLink1" runat="server" 
    NavigateUrl="~/vuelo/santiago-scl-buenosaires-bue-01_10_2013-05_12_2013">
    Vuelo de Santiago a Bs As para el dia 01/10/2013 al 05/12/2013
    </asp:HyperLink>

    Aqui es obvio que tambien podremos utilizarlo sin el webcontrol Hyperlink… pero no es recomendable porque no podremos mantener este tipo de enlaces en todo nuestra aplicación web.

  2. Creando automáticamente en modo diseño: Dejar que ASP.NET genere el enlace.. pasando los valores de los parametros

    Aqui nos aydamos de la expresion RouteUrl…

    <asp:HyperLink ID="HyperLink2" runat="server" 
    NavigateUrl="<%$RouteUrl:origen=santiago-scl,destino=buenosaires-bue,fechaSalida=01_10_2013,fechaRegreso=05_12_2013%>">
    Vuelo de Santiago a Bs As para el dia 01/10/2013 al 05/12/2013
    </asp:HyperLink>

    Aquí es mucho mas fácil mantener los enlaces a nuestras rutas.

  3. Creando desde codebehind:

    Aquí nos valemos de RouteValueDictionary y el método RouteCollection.GetVirtualPath

    SNAGHTML10a70dfb

 

 

 

Espero que sirva de ayuda o guía

 

Enlaces que te pueden ayudar

[ASPNET/IIS] Tener url mas amigables utilizando URL Rewrite (transparente a nuestra app)

Si queremos tener url mas amigables, ya es algo que debemos forzarnos en toda app web, para el buscador que nos visita e indexa y para entender mejor nuestra app por parte del usuario.

Por una pregunta que me hicieron aquí detallo la forma que tenemos de realizar esta tarea utilizando el modulo de IIS (y además dejo para otros post de como sería con lo que tenemos desde la ASP.NET MVC y en Webforms desde la versión 4.0 que es el Enrutamiento/Routes)

Tenemos algunas alternativas (para incluso para Webforms…)

  1. El modulo del IIS Url Rewrite (el de este post)
    Muy fácil y transparente para la app web… cualquiera sea no necesariamente ASP.NET
    http://www.iis.net/downloads/microsoft/url-rewrite
  2. También existen la posibilidad de redireccionar mediante HttpContext.RewritePath
    (lo bueno que lo tenemos desde la versión de ASP.NET 2.0)
    http://msdn.microsoft.com/es-es/library/system.web.httpcontext.rewritepath.aspx
  3. Pero desde la versión de ASP.NET 4.0 tenemos el Enrutamiento/Routes (idem a los que utilizamos en MVC)

Veamos entonces el punto 1… el módulo IIS URL Rewrite

¿Qué necesitamos mapear?

Lo que se requiere es poder mapear por ejemplo esta URL (un poco extensa)

http://localhost/PruebaLandingVueloConParametros.aspx?Origen=santiago-SCL&Destino=buenosaires-BUE&FechaSalida=01_10_2013&FechaRegreso=05_12_2013&Adultos=3&Child=3

A algo mucho mas amigable

http://localhost/PruebaLandingVueloConParametros/santiago-SCL/buenosaires-BUE/01_10_2013/05_12_2013/3/4

 

Url Rewrite

SNAGHTML1a09a0f8El modulo de IIS URL Rewrite utiliza reglas para evaluar y mapear la URL del request a la url que definimos, antes de ser procesado por un servidor web IIS.
Pero es mucho mas potente, incluso para utilizar en las reglas el encabezado HTTP y variables del servidor o para modificar  url del response (sobre escribir la respuesta)

Aquí veremos la pregunta concreta, como reescribimos

Entonces:

  1. Descargar el modulo del IIS image
  2. Definir una regla de reescritura para la url planteada
  3. Listo! (no hace falta hacer nada en la app web, ya que es transparente)
  4. ¿Dónde guarda el modulo las reglas? Web.config (podríamos escribir las reglas directamente allí)

 

 

 

 

 

1) Descargar el modulo del IIS

Tienes varios lugares donde obtenerlo…  y todos lo hacen a través de Web Plataform Installer

Que apuntan a la pagina de instalación de Web Plataform Installer

http://www.microsoft.com/web/gallery/install.aspx?appid=urlrewrite2

O directamente en nuestro IIS

SNAGHTML197cc6dc

SNAGHTML197e27c1

SNAGHTML197f8f0b

SNAGHTML19814407

SNAGHTML1983b012

Y dependiendo del idioma que hayamos descargo o tengamos configurado nuestro sistema operativo

SNAGHTML198b7b2d

Y allí realizas los pasos para agregar, e instalar directamente en el IIS. Esto deja listo para utilizarlo.

 

 

2) Definir una regla de reescritura para la url planteada

Las reglas de entrada básicamente tiene tres componentes

  1. Coincidencia de la cadena/Patrón: Hacer coincidir la cadena de dirección url.
    Se pueden utilizar expresiones regulares o wildard (que es comodín que se utiliza en el modulo de Redirección HTTP del IIS). En ejemplo utilizamos expresiones regulares
  2. Condiciones: Si se machea el patrón entonces se verifican las condiciones (pero pueden no tener condiciones) por ejemplo verificar si existe o no el archivo físico o directorio o alguna variable de servidor o encabezado HTTP
  3. Acción a tomar: Lo que se debe realizar si la cadena machea con el patrón de entrada y cumple las condiciones (podremos reescribir la url, definir una redirección – Response 3xx, abortar le petición o una respuesta personalizada)

SNAGHTML19c002a5

Importante/A tener en cuenta

  • Todas las reglas que agregamos se alojan en el web.config de la app que estamos manipulando
  • Las url originales quedan guardadas en una variable de servidor (HTTP_X_ORIGINAL_URL y UNENCODED_URL)
  • Las reglas se evalúan como se ingresan por esa razón se debe tener cuidado en las definición de las mismas (mirar en el web.config el orden se puede manipular allí o desde la interfaz de administración podremos ordenar de otra manera)
    SNAGHTML19c46be3

Entonces comencemos a armar nuestra Reescritura de la url

Agregamos mediante la interfaz que nos proporciona desde el administrador del IIS una regla en blanco…

SNAGHTML19b8570b

La url que queremos mapear era

http://localhost/PruebaLandingVueloConParametros.aspx?Origen=santiago-SCL&Destino=buenosaires-BUE&FechaSalida=01_10_2013&FechaRegreso=05_12_2013&Adultos=3&Child=3

A esto

http://localhost/PruebaLandingVueloConParametros/santiago-SCL/buenosaires-BUE/01_10_2013/05_12_2013/3/4

El Patrón para la url a mapear seria

^PruebaLandingVueloConParametros/([_0-9a-z-]+)/([_0-9a-z-]+)/([_0-9]+)/([_0-9]+)/([0-9]+)/([0-9]+)$

NOTA: A modo de ejemplo utilizo un patrón sencillo, pero la parte de origen y destino fechas podría ser algo mas “ajustado”, por ejemplo:

  • Para la parte origen destino: ([a-z0-9]+-[a-z0-9]{3})
  • Para la parte de fechas: ([0-9]{2}_[0-9]{2}_[0-9]{4})

 

SNAGHTML19c829c5

Podremos probar el patrón…

  • Datos de entrada para probar
    PruebaLandingVueloConParametros/santiago-SCL/buenosaires-BUE/01_10_2013/05_12_2013/3/4
  • Patron: Expresión Regular
    ^PruebaLandingVueloConParametros/([_0-9a-z-]+)/([_0-9a-z-]+)/([_0-9]+)/([_0-9]+)/([0-9]+)/([0-9]+)$

 

SNAGHTML19bcf3b7

Como vemos en los resultados de la prueba tenemos grupo de captura de las referencias inversa, los {R:x} que nos ayudaran en la acción a tomar para entregar a la aplicación el parámetro correcto con el valor y nombre correctos.

¿Como capturamos los Back-references (referencia inversa)?

En este ejemplo en particular cada vez que utilizamos expresiones regulares (e.r) y agrupamos dichas expresiones en paréntesis (e.r) podremos capturar un “grupo de captura”.

Si este grupo esta en:

  • Las condiciones entonces debemos hacer referencia a {C:x}
  • En los patrones o reglas de entrada entonces {R:x}, como lo demuestra en la prueba de entrada del patrón

En este ejemplo en particular no tendremos en cuenta las condiciones, así que vamos directamente a la acción a tomar…

 

Accionar a Tomar: Reescritura

Donde tendremos la dirección url a reescribir tomando las referencia inversas del patrón de entrada (los {R:x})

PruebaLandingVueloConParametros.aspx?origen={R:1}&destino={R:2}&fechaSalida={R:3}&fechaRegreso={R:4}&adultos={R:5}&child={R:6}

Nos quedaría así:

SNAGHTML19d25d82

Donde vemos

  • Destildar “Anexar cadena de consulta (querystring)” asi queda limpio la rescritura y no necesitaremos nada mas (aqui deberias evaluar si debes o no agregar el querystring en la acccion)
  • Destildar si queremos no “Dirección Url reescrita de registro” o sea logear en los logs del IIS la url reescritra
  • Y debemos tildar “Detener el procesamiento de las reglas siguientes”, para que no se evaluen las demas reglas

 

3) Listo! (no hace falta hacer nada en la app web, ya que es transparente)

Y en nuestra app? Sigue funcionando porque esto lo realiza el IIS independientemente de la app o tecnología que esta sirviendo (ASP.NET, PHP, etc)
Así que nuestro código no tiene cambio! Puedes utilizarlo tranquilamente…

 

4) ¿Donde guarda el modulo las reglas? Web.config

Esto nos queda en el web.config por supuesto dentro de la seccion <system.webServer><rewrite>…

<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<rewrite>
<rules>
<rule name="LandingVuelo" stopProcessing="true">
<match url="^PruebaLandingVueloConParametros/([_0-9a-z-]+)/([_0-9a-z-]+)
/([_0-9]+)/([_0-9]+)/([0-9]+)/([0-9]+)$"
/>
<action type="Rewrite"
                            url="PruebaLandingVueloConParametros.aspx?origen={R:1}&amp;destino={R:2}&amp;
fechaSalida={R:3}&amp;fechaRegreso={R:4}&amp;adultos={R:5}&amp;child={R:6}"

appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>

</configuration>

NOTA: A modo de visualización en este articulo las urls tiene un salto de línea (algo que no puede tener en el web.config)

 

Podríamos escribir las reglas directamente allí, algo que hacemos mas rápido (y nos gusta tocar XML)

 

 

 

Espero que les sirva de ayuda o guía.

[EVENTO] Jornadas de Actualización en Tecnologías Innovadoras #UNNE #Corrientes 6/Sep 2013

Tengo el agrado de invitarlos a las Jornadas de Actualización en Tecnologías Innovadoras el próximo Viernes 6 de Septiembre de 2013 a las 17hs (Lugar: UNNE-FACENA, 9 de Julio 1449, Corrientes, Argentina)

La hemos organizado Desarrollos NEA con la UNNE (Universidad Nacional del Nordeste) FACENA (Facultad de Ciencias Exactas y Naturales y Agrimensura) en una Jornada de Actualización Tecnológica; son una serie de charlas que si bien comienzan con estos temas, nos han comentando desde la UNNE que se vienen una serie con diferentes tecnologías; así que agendandose la fecha  para compartir unas horas intercambiando conocimiento.

En esta oportunidad veremos estos temas:

JornadasActualizacion-UNNE-Septiembre2013

 

 

Jornadas de Actualización en Tecnologías Innovadoras

  • Desarrollo de una red social con Visual Studio 2013 Preview y ASP.NET MVC 5
    Aquí entre Marcos Budimir (@MarkiBudi), Maximiliano Gonzalez Schweizer (@maxigs7) y Diego Cantero (@Mariano_D_C) y quien yo @fernandezja generaremos un proyecto donde mostraremos estas tecnologías:
    • Entity Framework Code First
    • ASP.NET MVC 5
    • Autenticación con Redes Sociales
    • ASP.NET Web API
    • Angular.js
    • SignalR
    • LESS, Web Essentials
    • Bootstrap
  • Inteligencia de Negocios con SQL 2012.
    Aquí Humberto Oraisón nos dará la Introducción al nuevo “Modelo de Datos Tabulares de SSAS”
    • Conceptos.
    • Ventajas y desventajas respecto del modelo tradicional de datos multidimensionales.
    • Introducción al lenguaje de consulta: DAX (Data Analysis Expressions).
    • Implementando una solución BI con datos tabulares.
    • Consumiendo datos tabulares con Excel 2013, SharePoint 2013 y Power View.
  • Infraestructura con Windows Server 2012
    Aquí Francisco Casco (@FranciscoACasco) tiene estos temas:
    • Active Directory
    • DHCP y RRAS
    • File Server (NTFS y Share)
    • GPO (Políticas de Grupo)
    • Remote Desktop Services
    • Virtualización (Hyper-V)

 

Esperamos contar con su presencia, están todos invitados…

[ASPNETMVC] Trabajar con directorios virtuales en IIS Express con ASP.NET MVC… cuidado con la physicalPath de la app raíz

imageHace unos días con Marcos, un compañero de trabajo, dimos con un inconveniente cuando tuvimos que trabajar con una aplicaciones ASP.NET MVC en directorio virtuales en el IIS Express; El inconveniente… era que cuando se cambia a que utilice un directorio virtual la app el IIS Express mantiene la configuración de la misma aplicación en el raíz, haciendo que las peticiones se respondan de ambas aplicaciones la raíz apuntando al mismo directorio que la nueva app con el directorio virtual… Si a alguno le paso y conoce como solucionarlo de otra forma me avisa!… Por lo pronto la solución rápida fue apuntar el la app raíz a otro directorio (directamente en la configuración del IIS Express, archivo applicationhost.config)

 

Paso a paso: Creando el proyecto y utilizando IIS Express

Al crear una aplicación ASP.NET MVC con el VS2012 Update 3 (lo digo por las dudas) por default la configuración para el servidor web es así:

SNAGHTML7153759f

Dicha configuración se encuentra en el archivo applicationhost.config
Que siempre se encuentra en alguna de estas ubicaciones:

%userprofile%documentsiisexpressconfigapplicationhost.config
%userprofile%my documentsiisexpressconfigapplicationhost.config
Dicha configuracion es algo asi (veras que por site tenemos un nombre para manipular el mismo y un id)

SNAGHTML72e9cdf4

En nuestro proyecto se encuentra en el archivo  de proyecto .csproj, si lo vemos diria algo asi

SNAGHTML72eecede

 

Utilizando un directorio virtual

Cuando creamos o utilizamos

SNAGHTML717f5535

Se crea una nueva app en la configuración del IIS Express…

NOTA IMPORTANTE: A la misma ubicación (mirando el physicalPath)

image

Esto quiere decir que si lo ejecutamos IIS Express levanta todas las app y sus respectivos directorios virtuales de nuestro site

SNAGHTML71a0f8c4

 

¿El problema de tener así en la maquina de desarrollo?

O sea, va seguir respondiendo a las peticiones  de ambas app.

Por ejemplo para acceder a las imágenes ambas aplicaciones

  • http://localhost:58876/images/yoda.jpg
  • http://localhost:58876/app1/images/yoda.jpg

 

Mapeando correctamente el path de los recursos al raíz de la aplicación web (operador ~)

NOTA: Si estas utilizando en MVC el motor de vista Razor (o el motor Webforms con ASP.NET Web Pages 2.0) con  simplemente deberías utilizar el operador ~ (raiz de la app) mas info aquí

<img src="~/images/yoda.jpg" alt="Yoda" />

Si estas utilizando el motor ASP.NET Web Pages 1 tendrias que utilizar la funcion @Href
<img src="@Href("~/images")/yoda.jpg" alt="Yoda" />

(esto sigue funcionando, solo que ahora no hace falta la funcion solo el ~)

Bueno y aquí el problema es cuando no utilizamos esto o algunas llamadas se realizaron sin tener en cuenta el directorio virtual.

Cuando estamos en desarrollando con IIS Express esta aplicación web en su directorio virtual… algunas peticiones ajax, llamadas a imágenes, estilos seguían funcionando y cuando desplegamos en el servidor ya en producción con solamente en el directorio virtual obviamente no iban a funcionar.

¿Entonces? Solución “express”…

Simplemente cambiamos el physicalPath del directorio raíz… así las peticiones de la aplicación raíz no deben funcionar.

SNAGHTML71dba3d3

 

Espero que les sirva de ayuda o guía (o para conocer de mi parte otra forma de realizar esta tarea)

 

[ASPNET] DLL y Optimización Dinámica en sitios web. Copiar DLL sin compilar todo el sitio web. Atributos optimizeCompilations y compilationMode

La pregunta básicamente es “Realizar modificaciones en algunas carpetas (BIN por ejemplo) Sin reiniciar la app

Bueno aquí debo hacer mención a Jesús Bosch que fue el que escribió este titulo en su pregunta en los foros (hace ya bastante tiempo pero lo tenia en borrador así que aquí esta para futuras referencias)

Ahora los enlaces/url a los post del foros son mas user-friendly (tienen el titulo al final), y se modifico la UI… date una vuelta por los Foros MSDN

Entonces en este post:

  1. Compilar? Muy pero muy breve introducción de compilación en ASP.NET…
  2. Cambios en BIN sin compilar todo el sitio (sin reiniciar) . Atributo optimizeCompilations
  3. Pensemos… en voz alta! Cuidados Especiales
  4. ¿Y si no queremos compilar nunca? compilationMode="Never" (solo para ASP.NET Webforms)

 

Compilar? Muy pero muy breve introducción de compilación en ASP.NET…

Como sabrás o te estas enterando si utilizas proyectos ASP.NET Websites compila el sitio en la primer petición, el codebehind y los archivos de código, lo que puedes prevenir precompilando todo el sitio que te dejo para investigar; En cambio si utilizas ASP.NET WebApp (Proyectos Web) puedes compilar en un único ensamblado, tendiendo un poco mas de “poder” sobre él (idem en proyectos MVC). Mas info sobre compilación:

Y en ASP.NET MVC? Ídem a Proyectos Web (Aplicaciones Web)… al fin y al cabo es una Proyecto Web ASP.NET solo que con componentes diferentes

Si bien a veces es bueno tener uno u otro, al realizar cambios en producción en algunos archivos reinicia la aplicación web… y allí es la pregunta:

 

Cambios en BIN sin compilar todo el sitio (sin reiniciar). Atributo optimizeCompilations

Si solamente quieres que no se reinicie todo el sitio se puede establecer el atributo optimizeCompilations en true de la sección compilation del web.config (mas info aquí)

Cuando se realizan cambios en archivos de nivel superior (léase en el global.asax, o carpetas App_Code, o BIN) se compila todo el sitio…. eso ya lo sabemos.

Textual de MSDN:

(…)Si desea poder cambiar los archivos de nivel superior sin tener que volver a compilar todo el sitio, puede establecer en true el atributo optimizeCompilations del elemento compilation en el archivo Web.config.Si el valor de optimizeCompilations es true, al cambiar un archivo de nivel superior, solo se vuelven a compilar los archivos afectados. (…)

<compilation 
optimizeCompilations="true">

Fix: para que funcione deberías tener estos hotfix dependiendo del Sistema operativo

Pero no es la panacea! deberías tener en cuenta algunos puntos…

Pensemos… en voz alta! Cuidados Especiales

(también esto esta en la pagina de MSDN)

  • Si uno no cambias alguna firma de un método, tus paginas que utilizan los assemblies (las dll) seguirán funcionado.
  • Si tienes métodos nuevos, las nuevas paginas utilizan las nuevo métodos y serán compiladas dinámicamente

NOTA Final: (…)Si desea utilizar el atributo optimizeCompilations para minimizar el tiempo de la compilación dinámica, deberá revisar atentamente cada cambio que realice en los archivos de nivel superior de un sitio y, si hay algún cambio que no sea seguro, deberá quitar temporalmente el atributo optimizeCompilations o establecer su valor en false.(…)

 

¿Y si no queremos compilar nunca? compilationMode="Never" (solo para ASP.NET Webforms)

Allí puedes utilizar la propiedad CompilationMode que sirve para establecer si se realiza o no esta acción sobre las Paginas (y/o UserControls), así que aquí estamos hablando solo de ASP.NET Webforms

O sea, debes precompilar todo el sitio (algo que hablamos mas arriba) o sino las paginas o usercontrol con código no funcionarían

Lo podemos escribir en la directiva de pagina, pero para todo el sitio va en el web.config en la seccion pages:

<configuration>
<system.web>
<pages compilationMode="Never" />
</system.web>
</configuration>

 

 

Enlaces

 

[Formación] Workshop de Scrum en el Informatorio (Resistencia, Chaco). Finalizado

La semana ante pasada tuve la invitación del Informatorio Chaco (Laboratorio de Capacitaciones Informáticas de la Provincia del Chaco) a través de Gilda (@gil2rom) y Noelia (@noeliapinto) para facilitar el tema Metodologías Agiles… sobre todo de Scrum

Nuevamente tuve el agrado de facilitarlo junto a Diego (@damorales)

Aquí la evidencia del encuentro… “los rostros” 😉

20130612-WorkshopScrumEnInformatorioChaco

Si bien tuvimos con Diego un par de horas donde pudimos recorrer:

  • Roles y Artefactos…
  • Reuniones…
  • y por sobre todo, Practicar…
    que fue un solicitud dentro de los temas, que era fácil entenderlo pero practicar seria un poco mas difícil.

Mas datos sobre el Informatorio:

  • Objetivo
    ”…formar a los jóvenes en las competencias necesarias para ingresar a la industria creciente de Software y Servicios Informáticos de la Provincia del Chaco…”
  • Informatorio Chaco – Laboratorio de Capacitaciones Informáticas de la Provincia del Chaco
    http://industria.chaco.gov.ar/enlaces/informatorio

 

Mas fotos

http://flic.kr/s/aHsjGoET89

[VisualStudio] TIP: Seguimiento elemento activo en el explorador de soluciones en VS2012

Seguramente las soluciones donde trabajas crecieron en cantidad de elementos (proyectos, componentes, elementos, clases, controladores, vistas, áreas con controladores, vistas – muy recursivo esto! je! ) y a veces estamos trabajando un proyecto particular para debugear pero para ir a un elemento relacionado en la misma carpeta estamos recorriendo el treeview del explorador de soluciones, abriendo o mirando previamente el path del elemento apoyando en el nombre del tab… para saber donde ir.

Entonces encontré este tip… que es mas bien una funcionalidad que viene deshabilitada por default… que es el “Seguimiento del elemento activo en el Explorador de Soluciones” (Track Active Item in Solution Explorer)

Si bien existían y existen plugins para realizar estas tareas (entre otras) como Resharper, o en la galería de extensiones para VS…  lo bueno que esto viene in-box

image

Lo podes encontrar en:

Tools > Options > Projects and Solutions

SNAGHTML583c8e3a

Lo que hace literalmente hablando… cada vez que tenemos un elemento activo en nuestro IDE en el explorador de soluciones se posiciona y selecciona dicho elemento.

 

Puede ser que moleste al principio, pero parece que nos ayuda o no?

Pruebalo! y cuéntame que te parece…

 

 

Esto me hizo acordar a a otro TIP que ahora lo tenemos in-box (y lo recomiendo): Enfocarnos en un Área Especifica (o carpeta). Muy útil en MVC

 

Referencia de Track Active Item in Solution Explorer: http://blogs.msdn.com/b/zainnab/archive/2010/03/29/track-active-item-in-solution-explorer-vstipproj0011.aspx

 

[ASPNETMVC] Atributos HTML con guiones medios… Método AnonymousObjectToHtmlAttributes (ejemplo databinding para KnockoutJS/AngularJs)

Armando un control personalizado necesitaba setear los valores de atributos HTML, lo de siempre class, rel, pero especialmente atributos data por ejemplo los que son necesarios los binding de los frameworks javascript MVVM como KnockoutJS, AngularJS
Estos atributos tienen esta forma: data-bind, ng-mode, ng-click

Si lo queremos insertar en un Textbox/TextboxFor en el parametro htmlAttibutes una propiedad con guion del medio en el nombre:

SNAGHTML165b12f9
NOTA: Aquí la @class esta para cuando en C# necesitamos utilizar una palabra reservada como nombre de propiedad de un objeto anónimo

Bueno es conocido que debemos colocar con guiones bajos es decir data_bind y convertirá en un atributo data-bind

Pero necesitaba realizarlo en un control personalizado… asi que en vez de “armar el código para realizar esto” investigue un poco como estaba armando el propio y simple textbox mirado el código fuente de NET Framework.

Di con este método estático HtmlHelper.AnonymousObjectToHtmlAttributes (en System.Web.Mvc.HtmlHelper) dentro de  que en la ayuda nos explica todo… es el responsable de armar estos atributos

SNAGHTML15b196e3

“…Reemplaza los caracteres de subrayado (_) por guiones (-) en los atributos HTML especificados….”

El código:

//from System.Web.Mvc.HtmlHelper
public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
RouteValueDictionary result = new RouteValueDictionary();

if (htmlAttributes != null)
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes))
{
result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
}
}

return result;
}

Entonces el código quedo algo así para armar la cadena de atributos a insertar en mi control personalizado atributosCadenaHtml.ToString();

...
var atributosFormateados =
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

var atributosCadenaHtml = new StringBuilder();
foreach (var atributo in atributosFormateados)
{
atributosCadenaHtml .AppendFormat("{0}="{1}"", atributo.Key, atributo.Value);
}
...

 

Enlaces que pueden ayudar

[VS2012] Descargar Visual Studio 2012 Update 2 como .iso (por fin!)

Hace un par de semanas salió el Update 2 para Visual Studio 2012 y para el TFS2012…  y por la oficina lo descargamos completo para no estar realizando esto cada vez que necesitábamos tanto las maquinas de desarrollo como las virtuales que armamos. Lo único malo era que la descarga completa lo hacia con para todos los idiomas disponible (esta descarga completa era de unos 1.8Gb), pero bueno era la alternativa de tenerlo “en modo offline”

Descargar .ISO

Pero recién me entero que se “alinearon los planetas” y ya esta la descarga oficial del ISO

Enlace directo al .iso (VS2012.2.iso) http://go.microsoft.com/fwlink/?LinkID=298533 (y por supuesto también de 1.8Gb)

NOTA: Seria bueno que el enlace al .iso estuviera en el enlace oficial de descarga del Update 2 😉
http://www.microsoft.com/en-us/download/details.aspx?id=38188 

 

Fuente:

http://blogs.msdn.com/b/visualstudio/archive/2013/05/03/announcing-availability-of-isos-for-visual-studio-updates.aspx

[EmplearTec] Curso Terminado: .NET Intermedio (Polo IT Corrientes)

Esta semana finalizo un curso que tuve el agrado facilitarlo con Federico y Juan Pablo (los tres jugadores mas a la derecha)

Curso NET Intermedio EmplearTec PoloITCtes 2012-2013 Con Titulo 1024px

El curso fue en el marco de las Becas EmplearTec Programación Orientada a .NET Intermedio que si bien son del 2012 (se comenzo en Diciembre y retomamos la segunda etapa en Febrero

Los temas que tratamos lo podríamos resumir en:

  • Patrones de diseño
  • Entity Framework
  • ASP.NET MVC 4.0
  • KnockoutJs
  • Bonus Track: SignalR (que no entro en el examen)

 

Bueno como siempre agradecimientos…

Porque si bien preparamos los temas y facilitamos ejemplos prácticos… siempre aprendemos cosas nuevas, muchas veces nuevos conocimientos técnicos (afianzar otros) pero también relaciones humanas e intercambio de ideas/opiniones.. asi que gracias a los que cursaron (y nos aguantaron)
Agradezco a la gestión del Polo IT Corrientes (desde Andrés y Fabián los que gestionan los cursos hasta Carlos que nos aguanta a los profesores). Esta gestión se realiza directamente con CESSI y el Ministerio de Trabajo y que hace posible estos tipo de cursos en Corrientes.

Esperemos que el contenido haya quedado (por lo menos de interrogante… a seguir profundizando)

 

Mas info Sobre EmplearTec

Que son las becas EmplearTec?

“Con el objetivo de fomentar más y mejor empleo en las áreas de software y tecnología a nivel nacional, el Ministerio de Trabajo, Empleo y Seguridad Social de la Nación, en conjunto con CESSI, y con el apoyo de empresas referentes del sector, ofrecen cursos de capacitación gratuita en todo el país.”

 

Similares que tuve la oportunidad de facilitar:

 

Tags :