Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
Mostrando entradas con la etiqueta aspnetmvc. Mostrar todas las entradas
Mostrando entradas con la etiqueta aspnetmvc. Mostrar todas las entradas
martes, 21 de enero de 2014
Usando la KatanaA través del formulario de contacto del blog, el amigo Carlos G. L. me enviaba una pregunta a raíz del último post de la serie sobre OWIN/Katana, relativo al uso de stage markers:
(...) entonces, ¿esto quiere decir que podemos utilizar un middleware para dar soporte CORS a soluciones basadas en la primera versión de WebAPI o en MVC 4?
Respuesta corta: sí. Siempre que se cumplan los requisitos de plataforma exigidos por Katana y los middlewares que queramos usar, nada impide hacerlo sobre aplicaciones con versiones anteriores de estos frameworks.

Y vamos con la respuesta larga…
martes, 3 de diciembre de 2013
ASP.NET MVCProbablemente ya lo sabréis, hace sólo unos días se lanzó la actualización para Visual Studio 2012 llamada “ASP.NET and Web Tools 2013.1” que hace posible el uso de MVC 5 desde esta versión del entorno de desarrollo.

Pues bien, tras instalarla, los que hayáis intentado probar ASP.NET MVC 5 desde Visual Studio 2012 probablemente os hayáis sorprendido con las pocas opciones que tenemos a la hora de crear proyectos de este tipo. Si bien están implementadas otras características disponibles en la versión 2013 como los scaffolders, el soporte para Razor 3, o la adopción de Bootstrap en la maquetación de vistas generadas, no podemos decir lo mismo de la aplicación del concepto “One ASP.NET“ a la creación de proyectos.
martes, 29 de octubre de 2013
ASP.NET MVC 5Hace poco pudimos vivir un día de esos en los que Microsoft publica nuevas versiones de todo. O casi: ASP.NET MVC 5, Web API 2, SignalR 2, Entity Framework 6, o Visual Studio 2013, entre otros. Muchas novedades que aprender, descubrir, probar… y sobre las que escribir, sin duda ;-)

ASP.NET MVC 5 es, quizás, el producto con menos cambios y novedades de todos los citados anteriormente. Ojo, esto no tiene por qué ser necesariamente malo: quiere decir que nuestro querido framework ha alcanzado ya un nivel de madurez importante y no necesita grandes cambios para seguir dándonos todo lo que necesitamos para crear aplicaciones web. Sin embargo, no puedo negar una cierta desazón ante la falta de esas novedades espectaculares que han venido acompañando entregas anteriores (¿recordáis cuando llegó Razor? ¡Uaaaaau!).

Pero antes que nada, deciros que ASP.NET MVC 5 completo (tooling y ensamblados) está disponible en estos momentos exclusivamente en Visual Studio 2013. Si utilizamos Visual Studio 2012 podemos descargar y utilizar los binarios usando Nuget, pero no habrá soporte a nivel de IDE hasta mediados de Noviembre, cuando se prevé que será lanzada una actualización del entorno.

Y dicho esto, vamos a comentar los cambios más destacados que acompañan a esta nueva versión.
martes, 18 de junio de 2013
ASP.NET MVC
En este tercer y último post de la serie (ir al primero o segundo) , vamos a ver una última técnica para realizar inyección de parámetros a acciones ASP.NET MVC que, aunque aporta menos a la hora de comprender las misteriosas interioridades del framework, es ciertamente mucho más cómoda y práctica en caso de que deseemos aplicar esta técnica.
martes, 11 de junio de 2013
ASP.NET MVCEn el primer post de la serie, vimos rápidamente en qué consiste la inyección de parámetros como fórmula para suministrar dependencias a una acción ASP.NET MVC, y realizamos una implementación sustituyendo unas pequeñas piezas del framework llamados action invokers que, como su nombre indica, son los responsables de invocar las acciones solicitadas por el usuario.
miércoles, 5 de junio de 2013
ASP.NET MVCNo hace demasiado tiempo describíamos por aquí cómo desacoplar controladores ASP.NET MVC mediante el uso de Inyección de Dependencias. En este caso, como en otros que hemos tratado, se hacía uso de uno de los “sabores” de esta técnica, que consiste en suministrar como parámetros al constructor de una clase todos aquellos componentes de los que depende para su funcionamiento. Sin embargo, esta no es la única forma de usar inyección de dependencias; hay otros métodos, quizás menos usados, como la inyección de propiedades o la inyección de parámetros en métodos que pueden ser interesantes en algunos casos y que, como mínimo, vale la pena conocer.
martes, 14 de mayo de 2013
ASP.NET MVCHasta ahora, los desarrolladores que queríamos usar Unity con ASP.NET MVC teníamos que recurrir a triquiñuelas o componentes no oficiales, como Unity.MVC3. No es que fuera especialmente incómodo ni que tuviera contraindicaciones, pero la verdad es que no dejaba de resultar curioso que no existieran adaptadores específicos “oficiales” para tecnologías tan difundidas como ASP.NET MVC, o WebAPI.

Pues bien, desde hace unas semanas tenemos disponible la versión 3.0 de Unity, que ha venido acompañando también a la reluciente versión 6 de la Enterprise Library. Como sabemos, esta creación del equipo de Patterns & Practices de Microsoft contiene un conjunto de componentes reutilizables llamados “application blocks” que resuelven problemáticas comunes en el desarrollo de sistemas, como logging, tracing, acceso a datos, gestión de excepciones y otras, incluyendo por supuesto inyección de dependencias e inversión de control.

En este post vamos a ver cómo podemos usar fácilmente esta nueva versión de Unity en nuestras aplicaciones ASP.NET MVC y algunas de las novedades que ofrece para este tipo de sistemas.
miércoles, 3 de abril de 2013
ASP.NETLa nueva versión de System.Web.Optimization traerá (aún está en beta) algunas novedades interesantes al sistema de bundling que se incluye de serie en los proyectos ASP.NET MVC y se distribuye a través de Nuget en el paquete Microsoft.AspNet.Web.Optimization.

En particular, vamos a centrarnos en una característica muy práctica si queremos utilizar una Content Delivery Network (CDN) externa (como la de Microsoft, Google o incluso una propia) para delegar a ella la carga de bibliotecas de script comunes, pero queremos a la vez proporcionar una alternativa local por si acaso ésta fallase debido a cualquier motivo.
martes, 5 de febrero de 2013
ASPNETMVCHace poco, en el post donde trataba la inyección de dependencias y desacoplamiento de Hubs de SignalR, el amigo Maxxx comentaba que podría estar bien ver cómo podríamos emplear las mismas técnicas con ASP.NET MVC.

Y ciertamente, me ha parecido muy interesante porque es un escenario que encuentro habitualmente en empresas de desarrollo: comprenden los beneficios de reducir el acoplamiento entre componentes, pero les parece algo demasiado complejo como para aplicar en su día a día porque desconocen cuáles son y cómo usar las herramientas de que disponemos para conseguirlo.

Por tanto, en este post vamos a ver, paso a paso y de forma totalmente práctica, cómo evolucionar desde un controlador MVC fuertemente acoplado a clases del modelo hasta otro totalmente desacoplado usando inyección de dependencias y contenedores de inversión de control.

Y aunque las técnicas y ejemplos que mostraremos están muy enfocados a controladores MVC, los conceptos tratados son aplicables en cualquier tipo de tecnología y arquitectura.
martes, 22 de enero de 2013
ASP.NET MVCHace poco veíamos que el nuevo sistema de routing usado por proyectos MVC 4 permitía una cierta configuración del formato de URL generadas por la aplicación al usar helpers como Url.Action() o Html.ActionLink(), y cómo usando una simple línea de código podíamos hacer que las rutas se generaran usando sólo minúsculas.
martes, 20 de noviembre de 2012
ASP.NET MVCEn formularios ASP.NET MVC, por defecto los campos ocultos no son validados en cliente. Es decir, aunque estos campos hayan sido generados usando los helpers e incluyan atributos con las restricciones, no serán tenidos en cuenta por jQuery validate a la hora de validar los datos del formulario antes de enviarlos al servidor.
lunes, 12 de noviembre de 2012
Algunos mensajes que genera ASP.NET MVC utilizan el idioma en el que hayamos instalado el framework. Por ejemplo, si hemos descargado la versión en inglés de MVC 4 y estamos usando en sistema operativo en español, podemos encontrarnos con textos de error como los mostrados en la siguiente captura de pantalla:



martes, 16 de octubre de 2012
ASP.NET MVCSi hay algo que me gusta de ASP.NET MVC es la cantidad de fórmulas que ofrece para aumentar nuestra productividad. Prácticamente cualquier código que estemos hartos de repetir una y otra vez puede ser encapsulado y reutilizado usando los puntos de extensión que nos proporciona el framework.

Hoy vamos a ver una solución a un problema al que seguro nos hemos enfrentado cientos de veces: la edición en formularios de propiedades de tipo enum.

1. El escenario

Imaginad que tenemos dos enumeraciones como las siguientes:
public enum Color
{
    Black, Blue, Red, Green
}

public enum Language
{
    English, Spanish, Italian, Portuguese
}

Usadas una clase del Modelo tal que:
public class Contact
{
    public string Name { get; set; }       
    public Language MainLanguage { get; set; }
    public Color? FavouriteColor { get; set; }
}
Y, a continuación, queremos crear un formulario de edición para la misma, con el código:
<h2>Edit contact</h2>
@using(Html.BeginForm())
{
    @Html.EditorForModel()
    <input type="submit" value="Send" />
}
imageComo era de esperar, el resultado una vez en ejecución es algo similar a lo que podemos ver en la captura de pantalla de la derecha.

Las propiedades MailLanguage y FavouriteColor, a pesar de ser enumeraciones, muestran como control de edición un simple cuadro de texto en el que podemos introducir cualquier cosa.

Y dado que son enum y podemos conocer sus valores de antemano, ¿no sería más lógico que la edición de estas propiedades se realizaran utilizando desplegables? 

2. Editor template para enums

Sin duda, la fórmula más sencilla y reutilizable para conseguir el objetivo que pretendemos es crear una plantilla de edición personalizada para las enumeraciones.

Como seguro sabréis, los editor templates proporcionan un mecanismo para generar controles de edición específicos para tipos de datos; podemos tener un editor para propiedades de tipo string (p.e., un cuadro de texto), de tipo DateTime (p.e., un cuadro de texto con un date picker), etc. Lo único que hay que hacer es crear en la carpeta /Views/Shared/EditorTemplates vistas parciales con el nombre del tipo de datos para el que se desea crear el editor (string.cshtml, datetime.cshtml, etc.).

Por tanto, probemos introduciendo el siguiente código en /Views/Shared/EditorTemplates/Enum.cshtml:
@model Enum
@{
    var isRequired = this.ViewData.ModelMetadata.IsRequired;

    var type = this.ViewData.ModelMetadata.ModelType;
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        type = type.GenericTypeArguments[0];
    }

    var values = Enum.GetValues(type);
    var items = (from object value in values
                 select new SelectListItem
                            {
                                Text = Enum.GetName(type, value),
                                Value = value.ToString()
                            });
}
@Html.DropDownListFor(m=>m, items, isRequired ? "Select...": "(None)")
Como se puede observar, prácticamente sólo hacemos tres cosas:
  • En primer lugar, determinamos la obligatoriedad de la propiedad a editar observando los metadatos del modelo.  
  • A continuación, creamos una lista de elementos de tipo SelectListItem recorriendo los valores disponibles en la enumeración. Observad que es necesario comprobar si el tipo que nos está llegando es anulable (Nullable<TEnum>)  y obtener el tipo de la enumeración de su parámetro genérico. 
  • Por último, usamos DropDownListFor() para generar el desplegable. En caso de tratarse de una propiedad obligatoria, añadimos un primer elemento con el texto “Select…”, y en caso contrario usamos el texto “(None)” para identificar el elemento nulo.
Y con esto ya tenemos hecho la mayor parte del trabajo, aunque aún nos falta un detalle. Por alguna razón que no llego a entender, ASP.NET MVC utiliza la plantilla string.cshtml (o el editor por defecto para el tipo string)  para editar las propiedades de tipo enum, lo cual nos obliga a indicar en las propiedades la plantilla a utilizar (las dos fórmulas usadas a continuación son equivalentes):
public class Contact
{
    public string Name { get; set; }  
    [UIHint("Enum")]
    public Language MainLanguage { get; set; }
    [DataType("Enum")]
    public Color? FavouriteColor { get; set; }
}
imageYa en ejecución, observamos que el resultado ha mejorado notablemente, como se puede apreciar en la captura de pantalla :-)

En este punto podríamos considerar que hemos alcanzado el objetivo que nos proponíamos, pero… ¿no os parece aún demasiado trabajo tener que decorar cada propiedad de tipo enumeración con estos atributos? ¿No podríamos dejar al framework que se encargue de estas minucias?

3. Proporcionando metadatos con metadata providers

Ya hemos hablado por aquí en varias ocasiones de los proveedores de metadatos, o metadata providers. De hecho, si no tienes claro lo que son, te recomendaría que leyeras el post “Mamá, ¿de dónde vienen los metadatos” que publiqué haces unos meses.

Muy resumidamente, se trata del mecanismo que obtiene los metadatos de las clases del Modelo desde donde se encuentren definidos. El proveedor por defecto los obtiene examinando las clases y sus propiedades mediante reflexión y obteniendo los atributos (anotaciones) que definen restricciones y otras características, pero podemos crear proveedores personalizados que las extraigan desde otras fuentes.

Y vamos a utilizar esta característica para evitar tener que especificar el atributo [UIHint] a las propiedades de tipo enum. El proveedor cuyo código veremos a continuación hereda del usado por defecto en ASP.NET MVC 4 (CachedDataAnnotationsModelMetadataProvider) y sobrescribe el procedimiento de obtención de metadatos:
public class EnumMetadataProvider: CachedDataAnnotationsModelMetadataProvider
{
    protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(
        CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
    {
        var metadata = base.CreateMetadataFromPrototype(prototype, modelAccessor);
        var type = metadata.ModelType;
        if (type.IsEnum ||
            (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && 
            type.GetGenericArguments().Length == 1 && type.GetGenericArguments()[0].IsEnum))
        {
            metadata.TemplateHint = "Enum";
        }
        return metadata;
    }
}
Observad que lo único que estamos haciendo es invocar el método de la clase base y, posteriormente, comprobar si el tipo de la propiedad es un enumerado o un tipo anulable de enumerado, en cuyo caso introduce en la propiedad de metadatos TemplateHint el nombre de la plantilla a utilizar (“Enum”).

Por último, ya sólo queda establecer un objeto de este tipo como proveedor de metadatos por defecto para la aplicación:
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        // ...

        ModelMetadataProviders.Current = new EnumMetadataProvider();
    }
}
De esta forma, por fin podemos eliminar de nuestra clase del Modelo los molestos atributos y todas las enumeraciones de nuestra aplicación se mostrarán en el formulario con la plantilla de edición que hemos creado anteriormente :-)

Publicado en: Variable Not Found.
martes, 9 de octubre de 2012
Me complace anunciaros que desde hace unos días tenéis disponible en CampusMVP mi nuevo curso de ASP.NET MVC 4, con el que espero seguir ganando fieles adeptos a esta tecnología ;-)

El temario es una completa y profunda revisión del utilizado en el curso de MVC 3, que tan buenas críticas ha recibido por parte de los alumnos que lo han seguido, pero más completo, adaptado a las novedades de la nueva versión, a las nuevas herramientas, y con un enfoque mucho más práctico.

Y para que veáis que no se ha escatimado en recursos, ahí va un vídeo de presentación muy chulo:
martes, 18 de septiembre de 2012
Seguro que alguna vez habéis notado que al generar URLs hacia acciones de una aplicación MVC usando helpers como Url.Action() o Html.ActionLink(), éstas son generadas usando mayúsculas y minúsculas según hubiéramos indicado en los parámetros de las llamadas:

Helper URL generada
@Url.Action("index", "home")/home/index
@Url.Action("List","Products", new{ Category="PC" }) /Products/List?Category=PC
@Url.Action("VIEWALL", "PRODUCTS") /PRODUCTS/VIEWALL

Como podemos ver, la URL resultante queda a criterio del desarrollador o, lo que es peor, al puro azar. A veces incluso no es algo que podamos elegir fácilmente, puesto que son generadas por otros componentes como T4MVC. Y no sé si desde el punto de vista del SEO tendrá su impacto, pero desde luego el ofrecer estas direcciones sin un aspecto unificado no da buena impresión.

En versiones anteriores a ASP.NET 4.5, esto podíamos solucionarlo creando helpers, o rutas personalizadas que, heredando de Route, realizaran esta conversión a minúsculas. Sin embargo, ahora disponemos de un mecanismo más cómodo para forzar que las URLs generadas sean normalizadas a minúsculas, así:
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.LowercaseUrls = true;
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        [...]
    }
}

Un detalle, sin duda interesante, para tener en cuenta en nuestros desarrollos.

Publicado en: Variable not found.
martes, 11 de septiembre de 2012
ASP.NET MVCEste es el mensaje que deberíamos interiorizar, si no lo hemos hecho ya, a la vista de las múltiples novedades introducidas en las últimas versiones de la plataforma ASP.NET y MVC:

Asíncronía = bueno

A grandes rasgos, la explicación es la siguiente: IIS tiene disponible un número limitado de hilos (threads) destinados a procesar las peticiones. Cuando llega una petición, uno de estos hilos es asignado en exclusiva a ella y permanecerá ocupado hasta que haya sido totalmente procesada. Si llegan peticiones cuando todos los hilos están ocupados, se introducen en una cola, también limitada. Cuando el tamaño máximo de esta cola ha sido superado, ya al servidor no le queda más remedio que responder con un error HTTP 503 al usuario indicándole que está seriamente ocupado.
martes, 17 de julio de 2012
ASP.NET MVCHace poco hablábamos de la creación de Display Modes personalizados en ASP.NET MVC 4, y veíamos cómo hacerlo usando la clase DefaultDisplayMode proporcionada por el framework, con la que podíamos cubrir la mayoría de necesidades comunes.

Así, veíamos cómo el siguiente código era suficiente para registrar un nuevo Display Mode llamado “iPhone”, que sería activado cuando en el identificador del agente de usuario (encabezado user-agent de la petición) incluyera el texto “iPhone”:
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
{
    ContextCondition = (context => context.Request.UserAgent.IndexOf
        ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
});
 
imageHecho esto, ya podíamos definir vistas alternativas a las habituales específicas para este dispositivo, cuyos nombres de archivo acabarían siempre en “.iphone.cshtml”. Observad que estamos usando la clase DefaultDisplayMode, a la que estamos facilitando la condición que debe cumplirse para que se active este Display mode.

Sin embargo, si pensamos crear muchas vistas específicas para dispositivos, podríamos encontrarnos con un maremagnum de archivos como el que veis en la captura de pantalla adjunta.

Obviamente, no es una situación fácilmente manejable, así que ¿por qué no cambiar la forma de nombrar los archivos dependiendo del Display Mode actual? Pues dicho y hecho, vamos a conseguir que cada dispositivo disponga de una carpeta específica para guardar sus vistas.

Heredando de DefaultDisplayMode

Si analizamos el código fuente de la clase DefaultDisplayMode, veremos que hay varios miembros virtuales que podemos sobrescribir para tomar el control, y uno de ellos es el método TransformPath(), encargado de transformar la ruta hacia el archivo físico donde está definida la vista teniendo en cuenta el nombre del Display Mode actual.

El código por defecto del método es el siguiente:
    protected virtual string TransformPath(string virtualPath, string suffix)
    {
      if (string.IsNullOrEmpty(suffix))
        return virtualPath;
      string extension = Path.GetExtension(virtualPath);
      return Path.ChangeExtension(virtualPath, suffix + extension);
    }
O sea, que se reemplaza la extensión del archivo, normalmente “.cshtml” por el resultado de concatenar el sufijo suministrado (el nombre del Display Mode) a dicha extensión. Por esta razón, el comportamiento por defecto del framework es utilizar construcciones como “nombrevista.iphone.cshtml”.

Si, como es el caso, queremos cambiar la ruta donde van a intentar localizarse las vistas, lo único que tenemos que hacer es crear una clase descendiente de DefaultDisplayMode, sobrescribir la forma de “montar” la ruta hacia la vista, y utilizar esta nueva clase para registrar los modos de visualización que nos interesen. Una posible implementación podría ser la siguiente:
    public class OrganizedDisplayMode: DefaultDisplayMode
    {
        public OrganizedDisplayMode(string displayModeId): base(displayModeId)
        {
        }
 
        protected override string TransformPath(string virtualPath, string suffix)
        {
            if (string.IsNullOrEmpty(suffix))
                return virtualPath;
 
            // Transforms /index.cshtml --> /suffix/index.cshtml
            int lastSeparator = virtualPath.LastIndexOf('/');
            virtualPath = virtualPath.Substring(0, lastSeparator) + 
                            "/" + suffix + 
                            virtualPath.Substring(lastSeparator);
            return virtualPath;
        }
    }
Vistas estructuradas por carpetasY en la inicialización de la aplicación ya podríamos registrar este Display Mode y asociarlo a la condición que esperamos que cumpla la petición:
  DisplayModeProvider.Instance.Modes.Insert(0,
     new OrganizedDisplayMode("iPhone") 
     {
        ContextCondition = 
           context => context.Request.UserAgent.Contains("iPhone")
     });
De esta forma, ya podemos organizar las vistas como podéis observar en la captura de pantalla de la derecha: cada dispositivo (o Display Mode registrado) dispondría de una carpeta en cuyo interior se encontrarían las vistas específicas para el mismo.

Y observad que su funcionamiento no se limita a las vistas asociadas a controladores concretos, la solución también sería válida en vistas compartidas (Shared) y con aquellas incluidas en áreas :-)

Publicado en Variable not found.
martes, 19 de junio de 2012
ASP.NET MVCUn post rapidito. Según puede consultarse en MSDN, ya tenemos confirmado que la versión 4.5 de .NET framework vendrá acompañada de un nuevo conjunto de atributos de validación para aplicar a las propiedades del Modelo en el espacio de nombres System.ComponentModel.DataAnnotations:
  • CreditCardAttribute, que puede ser utilizado para validar números de tarjeta de crédito.
  • EmailAddressAttribute, que validará direcciones de correo electrónico.
  • FileExtensionsAttribute, para validar extensiones en nombres de archivo.
  • PhoneAttribute, que indica cuándo una propiedad debe contener un número de teléfono válido.
  • UrlAttribute, que comprobará si el contenido de una propiedad es una URL válida.
  • CompareAttribute, que antes estaba disponible en System.Web.Mvc y ha “ascendido” a anotación de datos general, permite validar la igualdad de dos propiedades.
Pues bien, según se observa en este changeset del código fuente del framework, ya podemos asegurar que la versión final de MVC 4 incorporará adaptadores de cliente y servidor para que podamos utilizarlos de forma directa en nuestros desarrollos :-)

También se ha incluido soporte para el atributo MembershipPasswordAttribute, recientemente incluido en System.Web.Security, que comprueba si una contraseña cumple los requisitos establecidos para las mismas en el membership provider.

Publicado en Variable not found.
martes, 12 de junio de 2012
ASP.NET MVCSabemos que las editor y display templates son magníficas herramientas de productividad que nos facilitan la creación de potentes interfaces de usuario. Resumidamente, son las vistas creadas específicamente para generar el interfaz de edición o de visualización de un objeto concreto que son almacenadas en las carpetas EditorTemplates y DisplayTemplates, dentro de /Views/Shared.

Lo más habitual es utilizarlas para crear editores o visualizadores para tipos de datos concretos, en cuyo caso las vistas disponibles en las carpetas citadas anteriormente se llaman igual que el tipo de dato a editar o visualizar.

Por ejemplo, si tenemos una vista llamada int.cshtml en la carpeta /Views/Shared/EditorTemplates , será la utilizada como editor de propiedades de tipo entero. Algo parecido utilizamos por aquí, hace ya bastante tiempo, para integrar jQuery datepicker en nuestras aplicaciones.

También es habitual encontrar en estas carpetas plantillas vinculadas a propiedades u objetos de forma directa mediante el atributo [UIHint] (como en este post), mediante el cual se indica explícitamente qué plantilla debe utilizarse:
    [DisplayName("Long description")]
    [StringLength(140), Required]
    [UIHint("LimitedTextArea")]  // Use the template "LimitedTextArea.cshtml"
    public string Description { get; set; } 

Y otra alternativa, aunque quizás algo menos utilizada, es la posibilidad de indicar la plantilla a utilizar en la misma llamada al helper EditorFor() o DisplayFor() que provoca su renderizado:
    @Html.EditorFor(m=>m.Description, "LimitedTextArea")
Sin embargo, hay una posibilidad adicional, que curiosamente no es demasiado conocida, consistente en utilizar el atributo DataTypeAttribute para indicar la plantilla de edición o visualización a emplear para la propiedad a la que se aplica.

El funcionamiento es trivial: decoramos las propiedades con [DataType] suministrándole como parámetro el tipo de información que va a contener, y el sistema intentará localizar una plantilla con ese nombre.  Veamos un ejemplo:
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; }
 
    [DataType(DataType.Time)]
    public DateTime StartDate { get; set; }
 
    [DataType(DataType.Html)]
    public string LongDescription { get; set; }
En el momento de renderizar un editor (o un display) template para la primera propiedad, el sistema utilizará, si existe, el archivo EmailAddress.cshtml; en caso de no existir, intentará localizar un string.cshtml, y si tampoco lo encuentra generará un editor por defecto. En el segundo caso se realizará la misma operación con Time.cshtml, y el último de ellos usará la plantilla Html.cshtml como primera opción.

Podemos utilizar como nombre de plantilla todos los valores que encontramos en la enumeración DataType:
  • DateTime
  • Date
  • Time
  • Duration
  • PhoneNumber
  • Currency
  • Text
  • Html
  • MultilineText
  • EmailAddress
  • Password
  • Url
  • ImageUrl
Publicado en Variable not found.
martes, 5 de junio de 2012
ASP.NET MVC¡Bueno, pues parece que esto se mueve! Hace unos días ha sido publicada la Release Candidate de ASP.NET MVC 4 coincidiendo con la liberación de Windows 8 Release Preview y Visual Studio 2012 Release Candidate (que, de hecho, incluye de serie MVC 4 RC).

Y como viene siendo costumbre, vamos a dar un repaso a todo lo que encontramos en esta nueva entrega, que presumiblemente será la última (bueno, o penúltima, nunca se sabe) antes de la versión definitiva. Eso sí, para no hacer el post demasiado largo nos centraremos exclusivamente en los cambios más destacables y visibles que se han introducido respecto a la versión beta.