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 ;)

17 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!
viernes, 28 de diciembre de 2012
imageIndudablemente, hoy en día llevamos en el bolsillo ordenadores en miniatura mucho más potentes de lo que eran los equipos de escritorio hace unos años. Cualquier smartphone razonablemente actualizado es capaz de funcionar a más de 1Ghz y cuenta con varios gigabytes de memoria RAM, y, sin embargo, toda esta potencia está infrautilizada la mayor parte del tiempo.

Por otro lado, tampoco se puede dudar ya de la entrada de la nube en nuestras vidas. Cada vez desplazamos más capacidad de almacenamiento y proceso a infraestructuras fiables y escalables como las ofrecidas por proveedores como Microsoft, Amazon, Google, Oracle y otros, con un coste más que razonable. Esto, sin embargo, presenta un reto a medio y largo plazo: ¿serán las infraestructuras de estos proveedores suficientes como para soportar el crecimiento exponencial en servicios demandados por los usuarios?
lunes, 24 de diciembre de 2012
Feliz Navidad
Estimados amigos que estáis siempre ahí, os deseo unas muy felices fiestas navideñas, y espero que podáis compartirlas con familia, amigos y todos aquellos que apreciáis.

Y para el próximo 2013, espero que sea un año repleto de salud, amor, y trabajo (que cada uno elija el orden de estos factores ;-)) y, sobre todo, que sea el año en que se cumplan todos vuestros sueños y esperanzas, que seguro que ya va siendo hora ;-)

Nos seguimos viendo por aquí.

PD: Para los más frikis, os dejo con un post de 2007 de la selección Variable Not Found Classics: “Xmas Tree scan, el escaneo de puertos navideño”.
martes, 18 de diciembre de 2012
Me abuuuuurroNormalmente hacemos pruebas de nuestros desarrollos web sobre nuestro propio equipo, donde la transferencia de datos es prácticamente inmediata, en servidores de prueba ubicados en una red de área local, o incluso sobre un servidor de producción al que accedemos mediante una conexión a Internet de gran capacidad.

Sin embargo, nuestras aplicaciones web son muy diferentes cuando el cliente no dispone de una conexión de alta velocidad. Lo que nosotros percibimos en tiempo de desarrollo como una maravilla de agilidad, espectacularidad y facilidad de uso, puede ser un auténtico desastre para el cliente si no hemos tenido en cuenta que no todo el mundo puede disfrutar de conexiones de alta calidad.

Por esta razón, es interesante realizar de vez en cuando pruebas de nuestros sistemas reduciendo de forma artificial el ancho de banda disponible, de forma que podamos detectar en qué puntos podemos mejorar la experiencia del usuario en estos escenarios.
martes, 11 de diciembre de 2012
ASP.NETCuando trabajábamos con los Servicios Web de toda la vida, las herramientas de desarrollo incluían sistemas para generar la documentación básica de los servicios que implementábamos. El estándar WSDL (Web Services Description Language), era un lenguaje basado en XML que permitía describir las funcionalidades de un servicio web aportando gran cantidad de detalles sobre las operaciones, tipos de datos, o direcciones de acceso a las mismas.

Gracias a esto, los desarrolladores podíamos conectarnos fácilmente a un servicio para consultar sus especificaciones técnicas, o incluso generar de forma automática código cliente o proxies que facilitaran el acceso remoto a las funciones publicadas en la red.

Y para los que venimos de esos tiempos, una de las primeras dudas que surgen al comenzar a trabajar con WebAPI es si existe algo similar. Y la respuesta es sí, pero no ;-P
lunes, 3 de diciembre de 2012
Enlaces interesantesEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 19 al 30 de noviembre de 2012. Espero que os resulten interesantes :-)

.Net

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, 19 de noviembre de 2012
Enlaces interesantesPues celebrando el primer centenar de posts de esta serie, estos son los enlaces publicados en Variable not found en Facebook y Twitter, del 12 al 16 de noviembre de noviembre de 2012.

Espero que os resulten interesantes, al menos como en las 99 entregas anteriores :-)

.Net 

martes, 13 de noviembre de 2012
KnockoutHa pasado ya tiempo desde el último (y primer ;-)) post que escribí sobre Knockout, en el que hicimos una pequeña introducción al patrón Model-View-ViewModel y a Knockout.js, e incluso llegamos a implementar un pequeño ejemplo de código para ver cómo funcionaba el invento.

También presentamos en aquél momento dos conceptos que resultaban básicos para Knockout.js:
  • El binding, que es el mecanismo que permite mapear datos y acciones de la vista a propiedades y métodos del View-Model.
  • Las propiedades observables, que son aquellas a las que el framework realiza seguimiento de cambios con objeto de actualizar, cuando sus valores cambien, los elementos que dependan de ellas.
Estos dos conceptos están muy relacionados, y es conveniente tener claro de qué forma.
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:



lunes, 29 de octubre de 2012

Blogger invitado

Blogger invitado

Óscar Sotorrío Sánchez

Desarrollador independiente, MCP C#

Eterno aprendiz en esto de las tecnologías .NET y en especial con ASP.NET. Admirador de la filosofía de Internet y entusiasta de los nuevos modelos de negocio que rigen este mundillo. Blog: oscarsotorrio.com
Los closures, en castellano cierres o clausuras, son una potente característica de JavaScript que también podemos encontrar en otros lenguajes como C#, Objective-C, Eiffel y otros. Este concepto, que tradicionalmente pertenece a la programación funcional, tiene su origen en el lenguaje de programación Scheme.

En este artículo vamos a comenzar por identificar en el código cuándo se producen los closures para luego ver qué tienen de especial. Después pasaremos a ver algunos comportamientos que nos servirán para terminar completamente de entender cómo funcionan. Para finalizar, veremos un par de ejemplos de aplicaciones prácticas.
image7_thumb_thumb_thumb_thumb_thumbEstos son los enlaces publicados en Variable not found en Facebook y Twitter, del 22 al 26 de octubre de 2012. Poquilla cosa, he tenido una semana algo complicada, pero espero que al menos os resulten interesantes :-)

.Net

martes, 23 de octubre de 2012
Fundamentos de JavaScript y AJAX para desarrolladores y diseñadores webDurante los últimos días he tenido ocasión de disfrutar de la lectura del libroFundamentos de JavaScript y AJAX para desarrolladores y diseñadores web”, y no quería dejar de comentarlo por aquí.

Se trata de la obra más reciente del maestro José Manuel Alarcón, nacida con un ambicioso objetivo: ser útil tanto para desarrolladores  experimentados que buscan reforzar y ampliar sus conocimientos en Javascript, como para aquellos que desean comenzar trabajar con el lenguaje sin haber tenido contacto previo con el mismo.

Y desde luego, nadie mejor que el autor para conseguirlo: dilatada y reconocida experiencia en el mundo web, en Javascript (publicó su primer libro sobre el tema hace más de diez años), y una forma de escribir muy amena y cercana que hace que las trescientas ochenta páginas del libro se lean con mucha facilidad.

El índice completo podéis consultarlo en Scribd, pero, a grandes rasgos, el libro está dividido en los siguientes bloques:
  • Una amplia introducción al lenguaje, en cuyos primeros siete primeros capítulos se comienza a presentar Javascript desde cero, introduciendo ordenada y progresivamente conceptos como las variables, tipos de datos, funciones, operadores, estructuras de control de flujo, uso de matrices, textos, fechas o temporizadores, siempre usando ejemplos simples y directos.

    A pesar de que esta primera parte se destina sobre todo a los programadores noveles, me la he zampado por completo y puedo asegurar que he aprendido bastante con ella.

    El capítulo 8, que cerraría este bloque, cambia el ritmo de forma considerable entrando en aspectos avanzados, como la definición de objetos, constructores, el uso del siempre intrigante “this”, la herencia basada en prototipos, closures, y ocultación de miembros, entre otros interesantes asuntos.
          
  • Una vez conocido el lenguaje Javascript, a continuación se nos muestra cómo utilizarlo en el contexto de un navegador, realizando un completo recorrido por el DOM y las técnicas que nos permiten manipularlo de forma directa, sin usar jQuery ni frameworks similares. Aprenderemos a localizar elementos de la página, recorrerlos, realizar consultas dinámicas, y a modificar el contenido de la página en tiempo de ejecución.

    También se estudia en profundidad el tratamiento de eventos, su funcionamiento interno, los distintos modelos soportados por los navegadores, y cómo implementarlos de forma eficiente, por supuesto sin necesidad de emplear marcos de trabajo externos. Es, además, una referencia completísima de los eventos disponibles para cada tipo de elemento y la forma de procesarlos sin caer en particularidades de navegadores concretos.

    Para cerrar este bloque, se dedica un capítulo exclusivamente a hablar de Ajax, el uso del objeto XMLHttpRequest para enviar y recibir información  y los problemas más habituales que surgen cuando usamos esta técnica de intercambio de datos entre cliente y servidor. También se describen soluciones para la comunicación cross-site como JSONP (JSON with Padding), estudiado muy en profundidad, y CORS (Cross-Origin Resource Sharing).
     
  • Un último bloque muy orientado a la práctica, en el que se describen errores más comunes y la forma de trazar y depurar aplicaciones Javascript utilizando herramientas integradas en los navegadores, donde encontramos mecanismos similares a los que estamos acostumbrados en entornos de desarrollo como logs, profilers o breakpoints.
     
  • Por último, se dedica un capítulo en exclusiva para ver cómo lidiar con las misteriosas expresiones regulares, donde se demuestra que con la base adecuada no son tan fieras como parecen ;-)
Todos estos contenidos vienen, además, acompañados de innumerables ejemplos, trucos, consejos prácticos,  referencias históricas y anécdotas mediante las cuales se entienden los motivos de algunas de las “cosas raras” que vemos hoy en día al programar con Javascript, y que hacen aún más amena la lectura.

Con toda seguridad, un must have para todos los que aún no conocen Javascript y desean entrar por la puerta grande, y también para todos los que ya habíamos entrado hace años pero nos hemos ido dejando algunos detalles por el camino ;-)

Publicado en Variable not found.
lunes, 22 de octubre de 2012
image7_thumb_thumb_thumb_thumb_thumbEstos son los enlaces publicados en Variable not found en Facebook y Twitter, del 15 al 19 de octubre de 2012. Espero que os resulten interesantes :-)

.Net

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.
lunes, 15 de octubre de 2012
Enlaces interesantesEstos son los enlaces publicados en Variable not found en Facebook y Twitter, del 8 al 11 de octubre de 2012. Espero que os resulten interesantes :-)

.Net

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:
lunes, 8 de octubre de 2012
miércoles, 3 de octubre de 2012
TypeScriptSiempre he tenido la sensación de que Javascript no ha evolucionado de forma proporcional a las responsabilidades y expectativas que han ido depositando en él. El explosivo crecimiento que ha sufrido en los últimos años no venía acompañado de mejoras en el lenguaje que nos ayudaran a implementar aplicaciones cada vez más extensas y complejas, para las que es muy conveniente disponer de herramientas más potentes que las ofrecidas de serie por este veterano lenguaje.

Y Microsoft ha movido ficha. Hace un par de días, S. Somasesegar, vicepresidente corporativo de la división de desarrollo de la casa, presentó un nuevo lenguaje que pretende acabar con las tradicionales carencias de Javascript, al que han denominado TypeScript. Detrás de este nuevo “invento” está el mismísimo Anders Hejlberg, padre de C# y otras maravillas, que ya sabíamos hace tiempo que andaba liado con algo relacionado con Javascript.
lunes, 1 de octubre de 2012
image7_thumb_thumb_thumb_thumb_thumb[1][4]Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 24 al 28 de septiembre de 2012. Espero que os resulten interesantes :-)

.Net

martes, 25 de septiembre de 2012
PensadorMás de tres años hace ya desde la publicación en Variable not found de la última entrega de esta serie que tanto me divierte (entrega primera, segunda y tercera), y por fin he podido dedicar un poco de tiempo para organizar y seleccionar las citas que he ido anotando desde entonces.

Y aquí está el resultado, 101 nuevas frases célebres relacionadas con nuestro mundillo, que espero que os gusten tanto como las anteriores.

Este es el cuatro post de la serie compuesta por:
¡Que aproveche!
lunes, 24 de septiembre de 2012
image7_thumb_thumb_thumb_thumb_thumb[1]Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 17 al  22 de septiembre de 2012. Espero que os resulten interesantes :-)

.Net

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.
lunes, 17 de septiembre de 2012
Enlaces interesantesEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 9 al 14 de septiembre de 2012. Espero que os resulten interesantes :-)

.Net

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.
lunes, 10 de septiembre de 2012
image7_thumb_thumb_thumb_thumb_thumb[2]Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 3 al 8 de septiembre de 2012. Espero que os resulten interesantes :-)

.Net

martes, 4 de septiembre de 2012
Vamos alláDescansadito, las pilas cargadas, las mismas ganas de siempre, muchas cosas que contar… creo que no se me olvida nada, así que no ya hay excusa para seguir con el blog en letargo.

La verdad es que hemos tenido un veranito cargado de novedades. De hecho, nos encontramos a la vuelta de las vacaciones con versiones renovadas en todos los productos que usamos habitualmente para nuestro trabajo: sistemas operativos, plataforma .NET, entorno de desarrollo, EF, MVC… muchos juguetitos nuevos a los que hincarle el diente, y de los que seguro que hablaremos largamente durante los próximos meses.

Dicho esto, ¡queda inaugurada la temporada 2012-2013 de Variable not found!

Como siempre, nos vemos por aquí :-)
jueves, 26 de julio de 2012
MallorcaComo todos los años por estas fechas, me complace enormemente informaros de que este blog, y todo lo que le rodea, estará cerrado por vacaciones.

Hasta el próximo mes de Septiembre soltaré el timón de Variable not found y lo dejaré a la deriva, hasta que vuelva con energías renovadas y ánimos para afrontar el próximo año con la misma ilusión y dedicación que siempre.

En cuanto a los planes veraniegos, este año no voy a poder disfrutar de todo el tiempo libre que me merezco gustaría; afortunadamente (y digo afortunadamente, con la que está cayendo) tengo bastante trabajo y estaré liado prácticamente todo el verano.

Pero aún así, tendremos tiempo de hacer una nueva escapada a Mallorca, donde ya estuvimos el año pasado y estamos deseando repetir, y seguro que alguna que otra visita fugaz a playas cercanas de Cádiz y Huelva.

Nos vemos en unas semanillas :-)

¡Felices vacaciones, amigos!
lunes, 23 de julio de 2012
Enlaces interesantesDe nuevo esta semana no he tenido tiempo para retransmitir en directo estos enlaces, pero al menos sí para ir recopilándolos. Ahí van unos cuantos, que espero que os resulten interesantes.

.Net

Asp.net

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Y no olvidéis que normalmente podéis seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.

Publicado en Variable not found
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, 10 de julio de 2012
image7_thumb_thumb_thumb_thumb_thumbEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 18 al 23 de junio de 2012. Espero que os resulten interesantes :-)

.Net

Asp.net

Azure / Cloud

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Y no olvidéis que podéis seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.

Publicado en Variable not found
lunes, 2 de julio de 2012
Enlaces interesantesLa semana pasada he estado de viaje y no he podido ir retransmitiendo en directo los enlaces a artículos y recursos interesantes que encuentro en Internet, pero esto no significa que no haya estado atento a lo que se cocía… ;-)

Ahí van unos cuantos.

.Net

Asp.net

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Windows 8

Otros

Y no olvidéis que normalmente podéis seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.

Publicado en Variable not found
domingo, 1 de julio de 2012
MVP 2012Acabo de llevarme una gran alegría, y tengo la urgente necesidad de compartirla con todos vosotros: por segundo año consecutivo he tenido la inmensa fortuna de ser reconocido como Microsoft MVP en el área ASP.NET/IIS :-)

Es para mí todo un honor y un privilegio seguir formando parte de este grupo de apasionados de las tecnologías Microsoft, gente increíble con la que da gusto tratar, y con los que espero poder compartir más buenos ratos.

Por si alguno no sabe de qué se trata, el galardón MVP (Most Valuable Professional) es un prestigioso reconocimiento que otorga Microsoft a personas de la comunidad técnica que dedican parte de su tiempo a compartir con otros usuarios sus conocimientos y experiencias sobre productos y tecnologías de esta compañía. Si estás interesado en saber más sobre ello, aquí puedes leer bastante sobre el reconocimiento MVP.

Muchas gracias a todos los que lo habéis hecho posible de nuevo :-)

Ah, y ¡felicidades a todos los nuevos galardonados, y a los que repiten también este año!

Publicado en Variable not found.
jueves, 28 de junio de 2012
Pues resulta que alrededor de Sevilla vivimos y trabajamos un montón de gente a los que nos apasionan las tecnologías Microsoft. Algunos nos conocemos virtualmente, leemos nuestros blogs, nos comunicamos por Facebook, Twitter, u otros artilugios similares, pero realmente no tenemos apenas ocasiones en las que conocernos, vernos en persona y charlar de cosas raras mientras disfrutamos de unas cervezas.

Por esta razón, desde el grupo de usuarios .NET de Sevilla, CartujaDotNet, se nos ha ocurrido que podríamos aprovechar el veranito que ya tenemos encima para organizar el primer Cartuja.Networking, un encuentro informal exclusivamente dedicado a desvirtualizar, conocer compañeros de fatigas, charlar distendidamente sobre tecnologías, lenguajes, sistemas operativos, herramientas, o lo que se nos ocurra.

QCrossSin guión, ponentes ni protagonistas: la única intención es que nos conozcamos y le pongamos cara a la extensa comunidad de usuarios de tecnologías Microsoft de Sevilla, donde hay tanta gente interesante (¡interesantísima!), y con ganas enormes de compartir experiencias y conocimientos con los demás.

El día elegido para tan magno acontecimiento es el próximo miércoles 4 de julio, a las 20:00 de la tarde, en el QCross (zona Nervión). No hace falta registro ni nada parecido, simplemente presentarse allí y disfrutar de la compañía ;-)

¡¡No faltéis!!

Y si queréis estar al tanto de lo que se cuece en CartujaDotNet, noticias, eventos, o contactar con otros participantes, podéis uniros al grupo CartujaDotNet en Facebook, LinkedIn, o seguirlo a través de Twitter.

Más artículos hablando sobre este tema:

martes, 26 de junio de 2012
Modelo extenso de EF (tomado de http://mattduffield.wordpress.com/2011/06/23/working-with-large-entity-framework-models-in-visual-studio/)Los que hayáis tratado con modelos extensos en Entity Framework seguro que habéis sufrido bastante con Visual Studio 2010, puesto que las entidades y relaciones las representábamos obligatoriamente en un único diagrama y esto dificultaba enormemente su legibilidad y mantenimiento.
lunes, 25 de junio de 2012
AUGES: ASP.NET User Group EspañaEl próximo miércoles 27 de junio de 2012, de 19:00 a 21:00 (horario peninsular español), tenemos un interesante evento en AUGES que, sin duda, nos sacará de dudas a los muchos desarrolladores ASP.NET que lo más que sabemos de SharePoint es que existe ;-)

El cartel oficial del evento es el siguiente:

SHAREPOINT PARA APLICACIONES EN ASP.NET DESDE CERO

image¿Eres programador ASP.NET y no sabes nada acerca de SharePoint? No te preocupes, en AUGES hemos preparado este evento para que aprendas desde cero sobre está plataforma de Microsoft que está pegando muy fuerte y que ya usan millones de clientes en todo el mundo. Veremos las bases de la plataforma, los servicios, buenas practicas, el IDE de desarrollo… No puedes perdértelo!!!
Ponente
Edin Kapic que es Key Consultant en Pasiona consulting, con más de 6 años de experiencia en Sharepoint, ponente en la European Sharepoint Conference de Berlín y miembro de Grupo de Usuarios de SharePoint de Cataluña – SUG.CAT.

Os recuerdo que se trata de un Webcast, o sea, que podéis asistir a este evento desde vuestro sillón favorito, acompañados de una buena cerveza y un saco de palomitas. Y por supuesto, es totalmente gratuito.

Lo único que debéis hacer para poder asistir es registraros:
Esperamos veros por allí ;-)

Publicado en Variable not found.
image7_thumb_thumb_thumb_thumb_thumb[2]Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 18 al 23 de junio de 2012. Espero que os resulten interesantes :-)

.Net

miércoles, 20 de junio de 2012
Barra invertidaDesde los tiempos de MS-DOS llevamos utilizando la barra invertida para separar los nombres de directorio cuando indicamos una ruta hacia un archivo o carpeta, pero, ¿os habéis preguntado alguna vez por qué esto es así?

Como siempre ocurre, nada es fruto del azar.

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.
lunes, 18 de junio de 2012
Enlaces interesantesEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 11 al 16 de junio de 2012, y algunos más que no me dio tiempo a publicar. Espero que os resulten interesantes :-)

.Net

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.