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!
Mostrando entradas con la etiqueta desarrollo. Mostrar todas las entradas
Mostrando entradas con la etiqueta desarrollo. Mostrar todas las entradas
martes, 4 de marzo de 2014

El operador “?.”, también llamado safe navigation operator, era la característica más demandada para el lenguaje C# en Uservoice, uno de los principales canales utilizado por Microsoft para obtener feedback e ideas a aplicar en nuevas versiones de sus productos, y parece que definitivamente se está considerando la posibilidad de incluir este útil azucarillo sintáctico tanto en C# como en VB.

Para los que no lo conozcáis, se trata de una construcción que permite acceder a propiedades de objetos sin temor a las null reference exceptions lanzadas cuando estos objetos son nulos.
martes, 4 de febrero de 2014
ASP.NET MVCEn ASP.NET MVC, TempData es un mecanismo de lo más socorrido cuando se pretende hacer persistir información entre distintas peticiones de forma sencilla.
Hace ya bastante tiempo hablamos por aquí de cómo funciona, aunque resumidamente podríamos decir que se trata de un almacén temporal en el que podemos guardar datos desde una acción y consultarlos desde otra, aunque sea en peticiones distintas; la información se quedará almacenada hasta que sea obtenida por primera vez, momento en el que será eliminada del repositorio utilizado.

El principal problema que encontramos al utilizarlo en proyectos reales es que la información se guarda en variables de sesión, lo que en determinados escenarios puede ser muy costoso o simplemente imposible, y esto hace que descartemos su uso y que tengamos que inventar alternativas para solucionar problemas que usando TempData ya tendríamos resueltos.
sábado, 28 de diciembre de 2013
GUID Colliding SequenceLos GUID (Globally Unique Identifier) son una serie de 16 bytes generados pseudoaleatoriamente que se suelen utilizar para identificar de forma única objetos, dispositivos, componentes, o prácticamente cualquier cosa. Y, a diferencia de otros tipos de identificadores, el “única” debe ser interpretado de forma global, es decir, es virtualmente imposible que un GUID utilizado para un elemento se repita en otro equipo, lugar o sistema.

No hay magia negra en esto, es pura matemática. El número de combinaciones posibles es 2128; dicho así no parecen demasiadas, pero para que os hagáis una idea de las magnitudes, serían algo así como 3.400.000.000.000.000.000.000.000.000.000.000.000.000 valores distintos, número arriba o número abajo ;-). Si os parece difícil que os toque la lotería, supongo que podréis intuir lo poco probable que es que existan colisiones si decidimos seleccionar un GUID, por ejemplo, como campo clave en filas de una base de datos, o como nombres de fichero que queremos asegurar que sean únicos. Y así lo hemos hecho durante años.

Y todos los que los usamos seguiríamos tan felices si no fuera por ese pequeño matiz que he deslizado al comienzo del post: la pseudoaleatoriedad del algoritmo de generación utilizado, que va a provocar un colapso el próximo 11 de febrero debido al efecto denominado GUID Colliding Sequence.
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, 21 de mayo de 2013
Sabemos que el uso descontrolado de la carga diferida o lazy loading puede echar abajo el rendimiento de nuestra aplicación, puesto que se generan peticiones al motor de datos al intentar recuperar entidades relacionadas cuando intentamos acceder a ellas. Sin embargo, no son pocos los casos en los que me encuentro que no se está usando apropiadamente, provocando un rendimiento terrible en el acceso a datos de las aplicaciones.
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.
martes, 12 de marzo de 2013
SignalRCuando desde un cliente javascript consumimos los servicios suministrados por un Hub de SignalR, lo habitual es usemos los proxies generados automáticamente, para lo que solemos incluir en nuestra página una referencia al script “/Signalr/Hubs” según la ruta por defecto.

Sin embargo, puede haber casos en los que no nos interesa este comportamiento y preferimos generarlo de forma manual para, por ejemplo, incluirlo en un bundle o distribuir el archivo a través de una CDN. Veamos cómo conseguirlo.
martes, 5 de marzo de 2013
Anónimo
Venga, lo confieso: yo también he generado desde mis aplicaciones contenidos HTML y los he enviado al cliente en un archivo con extensión XLS, incluso modificando el content-type, para que pareciera un documento de hoja de cálculo. Durante años. Y también le he dicho a mis clientes que el molesto mensaje que aparece al abrirlo desde Excel, el que indica que el contenido del archivo no coincide con la extensión del mismo, es algo normal.

Pero esto se acabó desde que descubrí ClosedXML, un magnífico componente para .NET basado en el estándar OpenXML que permite la generación de archivos Excel “de verdad”, con formato, estilos, fórmulas, rangos, filtros, y casi todo lo que se nos pueda ocurrir.
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.
miércoles, 16 de enero de 2013
imageCuando estamos implementando Hubs de SignalR, podemos encontrarnos fácilmente con que éstos necesitan utilizar componentes externos para llevar a cabo su tarea. Por ejemplo, es bastante probable que un servicio en tiempo real proporcionado por un Hub tenga que utilizar una clase de servicios o cualquier otro componente externo de una aplicación, como en el siguiente código:
public class MyHub: Hub
{
    public Task sendMessage(string text)
    {
        using (var services = new LogServices())
        {
            services.Log(Context.ConnectionId, text);
            return Clients.All.receiveMessage(text);
        }
    }
}
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
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.
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:



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.
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.