Categoría: ASP.NET MVC

Creando un servidor NuGet propio para distribuir nuestras librerías

Creando un servidor NuGet propio para distribuir nuestras librerías

Algo que nos puede pasar de forma habitual cuando llevamos un tiempo desarrollando aplicaciones es que tenemos nuestras propias librerías para solucionar problemáticas comunes que se repiten de forma periódica. Básicamente lo que tendremos como resultados son DLLs que estaremos exportando de las librerías y referenciándolas desde los proyectos que las necesiten.

Por supuesto que esto es muchísimo mejor que tener la lógica común duplicada en todas las aplicaciones, pero también tiene sus desventajas, las cuales estarán en mayor o menor medida dependiendo de las características de las librerías y la cantidad de aplicaciones que la usen.

La principal es la distribución manual que debemos hacer de ese archivo para todas las aplicaciones clientes que deban usarlo. Normalmente lo que hacemos es copiarla desde otro proyecto que ya la esté usando. Además hay más problemas, ya que al hacer esto vamos a estar subiendo al repositorio de control de código fuente este archivo binario lo cual no deberíamos hacer. Más problemas tendremos cuando nuestra librería evolucione y tenga distintas versiones: ¿cómo sabemos cuál es la que tiene cada aplicación, la que necesitamos nosotros, si hay una nueva versión disponible, las dependencias que tiene cada una de esas versiones?

Está claro que la solución de todo esto es conocida desde hace tiempo, que es tener un paquete Nuget que encapsule todo esto. Pero necesitamos un servidor que nos provea los paquetes y en determinados casos (sobre todo en entornos empresariales) no podemos subir las librerías que se desarrollen en el repositorio público nuget.org

¿Entonces que hacemos? Sencillo, creemos nuestro servidor Nuget propio.

Básicamente es un sitio ASP.NET corriendo en algún entorno al que podamos acceder (puede estar expuesto a internet, en una intranet o hasta en nuestro equipo) con algunas particularidades. Veamos cómo crearlo:

Seguir leyendo “Creando un servidor NuGet propio para distribuir nuestras librerías”

.NET Standard, una librería para dominarlos a todos

Como he comentado en uno de los posts anteriores, en una de las charlas que he dado en el #NetRaf2017 comenté el estado de la plataforma .NET en el 2017. Uno de los puntos interesantes para comentar en mayor detalle es el asociado a .NET Standard, una librería que llega para dominarlos a todos.

Estado actual

Al día de hoy tenemos 3 grandes pilares que conforman la plataforma .NET, cada uno con un propósito bien definido (y muy distinto del que tienen los demás pilares):

NetStandard - Pilares.png

Veamos cada uno en más detalle:

.NET Framework:

Es la alternativa que veníamos usando hasta el día de hoy en el desarrollo de nuestras aplicaciones, también conocida como Full Framework en la actualidad. Se distribuye con el sistema operativo (es lo que estamos acostumbrados hasta el día de hoy, para correr una aplicación .NET debíamos tener la versión correspondiente del Framework instalada en el equipo.

.NET Core:

Es la versión multiplataforma del Framework, más reducida y compacta. Tiene un énfasis muy fuerte en lo que es la optimización del rendimiento, además de dar muchas soluciones a los desarrolladores de forma nativa que antes requerían siempre instalar dependencias adicionales. Lo podemos ver como una versión aggiornada del Full Framework. Dentro de los cambios que introduce, el Framework se distribuye con la aplicación, por lo cual las aplicaciones que hagamos son 100% autocontenidas.

Xamarin:

Plataforma que nos permite hacer desarrollos que corran en gran parte de las aplicaciones móviles, basada en el runtime de Mono (más detalles en este post que escribí introduciendo a Xamarin). Al igual que con .NET Core, el Framework se distribuye con la aplicación, lo cual hace que estas aplicaciones tengan un tamaño final más alto que una equivalente hecha en Java para Android o en Swift para iOS.

Lo que pasa aquí es que cada una de estas plataformas tiene una forma diferente de implementación, particularmente en las API’s a bajo nivel que cada una implementa:

Seguir leyendo “.NET Standard, una librería para dominarlos a todos”

Rider, un IDE multiplataforma para .NET

Rider, un IDE multiplataforma para .NET

Uno de los puntos que podemos marcar como desventaja en lo que es el desarrollo en .NET es la poca variedad de IDE’s con la que contamos, además de estar atados a Windows como sistema operativo.

Esto es algo que está cambiando en el último tiempo con el cambio de enfoque producido por la salida de .NET Core y por ende la posibilidad de usar otros IDE’s e incluso otros sistemas operativos. Una de las alternativas es ofrecidas por Microsoft es VS Code, pero al igual que las otras alternativas pueden quedarse un poco reducidas en funcionalidad en comparación a lo que es Visual Studio (aunque esto inevitablemente lo haga pesado).

Hace un tiempo terminé encontrando una alternativa interesante: Rider.

Rider es un IDE para desarrollo .NET que se puede ejecutar en Windows, macOS y Linux. Desarrollado por JetBrains, Rider toma como base IntelliJ, un IDE base muy bien logrado tanto desde el punto de vista de la usabilidad, personalización y del rendimiento. Además de que incorpora de forma nativa ReSharper. Al menos como estoy acostumbrado a usar algunos IDE’s de esa plataforma (especialmente Android Studio), la experiencia de uso me dejó muy buenas sensaciones.

En este post veremos como realizar la instalación en Ubuntu 17.04 y unos ejemplos de uso. Lo primero que haremos es proceder a su descarga desde el sito oficial a través del siguiente link.

Una vez finalizada la descarga del mismo (unos 350 MB) iremos a la carpeta donde lo descargamos y aplicaremos los siguientes comandos:

tar -xf riderRS-171.4456.199.tar.gz
chmod -R 777 Rider-171.4456.199
cd Rider-171.4456.199
cd bin
./rider.sh

Nota: los nombres de carpeta están asociados a la versión que bajé al momento de escribir este post, el cual puede variar al momento en el que lo estén usando.

Una vez finalizado esto, ya podremos comenzar con la ejecución de Rider en nuestro equipo:

Rider - Portada.png

Lo siguiente que deberemos hacer es instalar las dependencias para permitir la compilación y ejecución de las aplicaciones .NET

Seguir leyendo “Rider, un IDE multiplataforma para .NET”

Documentación automática en ASP.NET WebApi y soporte para arquitectura en capas

Buenas!

Como vimos en el post anterior, es muy sencillo el poder tener una documentación automática y detallada de nuestras WebApi’s. Sin embargo, el enfoque propuesto solamente nos sirve cuando todas las clases involucradas están en el mismo proyecto web.

Esto muchas veces no necesariamente es así. En una arquitectura en capas normalmente tendremos un proyecto separado con las clases que representan las entidades del dominio de nuestra aplicación, las cuales formarán parte tanto de requests y responses de la API. Además de que este esquema (con las clases de entidades separadas en otro proyecto) nos permite compartirlas de forma directa (a través de la DLL resultante) a los clientes de la API, por lo cual es una alternativa más que válida para cualquier caso real de implementación.

Veamos el siguiente ejemplo, donde tenemos nuestro proyecto web (WebApi) y una biblioteca de clases con nuestras entidades que interactuan en la API (WebApi.Contracts). En la API tenemos el controlador UsersController que retorna/recibe instancias de User:

DocumentacionWebApiOtrasAssemblies - EstructuraProyecto

Donde la clase User de contratos tiene el siguiente contenido:

namespace WebApi.Contracts
{
using System;
using System.ComponentModel.DataAnnotations;
/// <summary>
/// Representa un usuario de la aplicación.
/// </summary>
public class User
{
/// <summary>
/// Identificador.
/// </summary>
[Required]
public int Id { get; set; }
/// <summary>
/// Nombre.
/// </summary>
[Required]
[MinLength(10)]
[MaxLength(200)]
public string Name { get; set; }
/// <summary>
/// Fecha de nacimiento.
/// </summary>
[Required]
public DateTime BirthDate { get; set; }
}
}

view raw
User.cs
hosted with ❤ by GitHub

Al ejecutar nuestra aplicación e ir a la documentación de la API, veremos que están las propiedades de la clase pero no la documentación que nosotros le hemos agregado:

Seguir leyendo “Documentación automática en ASP.NET WebApi y soporte para arquitectura en capas”

ASP.NET WebApi: Documentación automática de nuestras API’s

ASP.NET WebApi: Documentación automática de nuestras API’s

Uno de los puntos importantes en el desarrollo de nuestras API’s RESTfull es tener una documentación adecuada para permitir y facilitar la tarea de integración de distintos clientes. Esto se debe de cierta forma a la diferencia que existe con respecto a un servicio SOAP, donde sí existe un archivo que contiene toda la definición del servicio y se utiliza para su integración.

En el caso de ASP.NET y sus servicios WebApi, esta funcionalidad viene integrada de forma nativa en el proyecto básico de este tipo. Luego de crearlo podremos ver la existencia del área HelpPage, la cual se encarga de crear la estructura de documentación asociada a nuestra API.

WebApiDoc - Area

Si ejecutamos la aplicación veremos en el menú superior el acceso API, el cual nos redirigirá al contenido de esa área.

WebApiDoc - Access

Seguir leyendo “ASP.NET WebApi: Documentación automática de nuestras API’s”

Internacionalización: soporte a formato de escritura Right-to-Left en ASP.NET MVC

Internacionalización: soporte a formato de escritura Right-to-Left en ASP.NET MVC

Uno de los temas pendientes en esta serie de post’s de internacionalización que estamos viendo es el soporte a culturas con sentido de escritura de derecha a izquierda en ASP.NET MVC (Right-to-Left o su acrónimo RTL, el cual usaremos de aquí en adelante). Esto será necesario cuando nuestra aplicación deba dar soporte a culturas que utilizan dicho formato de escritura, como por ejemplo sucede con el árabe.

Siguiendo con el ejemplo que venimos utilizando en el post anterior lo primero que haremos será dar soporte al árabe como cultura de nuestra aplicación. Para ello inicialmente crearemos el archivo de recursos asociado a la cultura árabe, el cual utiliza la sigla “ar” y agregaremos el contenido de cada recurso en su idioma:

InternacionalizacionRTL - CrearRecursos

NOTA: Todo el contenido que usemos en este post escrito en árabe está traducido con Google Translate ya que no conozco dicho idioma. Si alguien conoce del idioma y considera que la traducción no es la apropiada se agradece el comentario.

Lo siguiente será agregar tanto el link que permite el acceso a dicha cultura, el valor dentro de las constantes de las culturas soportadas y la lógica mínima para reconocer y establecer dicha cultura con nuestro esquema de rutas donde se visualiza la cultura.

Seguir leyendo “Internacionalización: soporte a formato de escritura Right-to-Left en ASP.NET MVC”

URL’s internacionalizadas en ASP.NET MVC

Hace algunos meses en una entrada asociada a Internacionalización vimos cómo cambiar la cultura manualmente en ASP.NET MVC. En el mismo continuamos con mejoras sobre la internacionalización de nuestra aplicación para que más allá de reconocer de forma automática la cultura del navegador del usuario le demos la posibilidad de que pueda cambiarlo.

Algo que venía quedando pendiente de los post’s anteriores sobre este tema es el poder reflejar en la URL la cultura en la que se está visualizando el contenido. Esto tiene varios propósitos:

  • SEO: Como podemos ver en la documentación de Google asociada a la internacionalización, se recomienda hacer visible la cultura de la página que se está visitando. Esto da una mejora en lo que a indexación por parte del motor de búsqueda se refiere.
  • Usabilidad: Además del propósito del punto anterior, le permitir al usuario que utiliza nuestra aplicación el poder ver la cultura correspondiente al contenido que está visualizando. Esto también aplicaría a la hora de compartir ese contenido con otros usuarios.
  • Diseño: Podemos decir que es mucho más natural en el diseño y estructura del contenido de nuestra aplicación que el acceso según cada cultura se vea reflejado en diferentes URL’s.

Para esto continuaremos con lo ya visto en el post mencionado y en toda esta serie de internacionalización, modificando y ajustando algunos aspectos.

Lo primero sobre lo que debemos trabajar es en que la cultura sea visible en la URL de nuestra aplicación, trabajando para ello en las rutas configuradas. En ASP.NET MVC esto se encuentra en el archivo App_Start/RouteConfig.cs, teniendo la ruta por defecto el esquema {controller}/{action}/{id}. Como no queremos cambiar el comportamiento de ese esquema de rutas debemos modificarlo para agregar la cultura pero sin modificar el comportamiento base con las implicancias que conlleva.

Seguir leyendo “URL’s internacionalizadas en ASP.NET MVC”

Eventos de conexión en SignalR

Avanzando con la serie asociada a SignalR hay un punto que nos puede ser muy útil a la hora de diseñar la interacción de nuestra aplicación: los eventos de conexión.

Explicándolo de forma muy simplificada, hay tres cosas que pueden suceder en el ciclo de vida de la conexión entre el servidor y cliente:

  • Inicio de la conexión
  • Finalización de la conexión
  • Reconexión

Los dos primeros sucederán en todos los casos, ya que siempre se creará y finalizará una conexión. En cambio la reconexión solamente se dará en aquellos casos donde haya una interrupción momentánea en la conexión entre las partes.

Lo que nos ofrece SignalR es el poder agregar lógica ante el suceso de estos eventos, pudiendo personalizar alguna situación o agregar comportamiento adicional, tanto del lado del servidor como del cliente.

Comenzando por el lado del servidor, la clase Hub – de la cual heredan nuestras propias implementaciones – tiene los métodos necesarios para la gestión de la conexión y desconexión de cada uno de los clientes del mismo. Esto lo hace a través de métodos virtuales, lo que hace que en nuestra implementación podamos realizar un override de los mismos, agregando la lógica de negocio propia además de invocar a la implementación base.

La siguiente porción de código es la definición de la clase Hub provista en las librerías de SignalR, donde podemos observar los tres métodos virtuales que nos servirán para este propósito:

using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Hubs;
namespace Microsoft.AspNet.SignalR
{
public abstract class Hub : IHub, IUntrackedDisposable, IDisposable
{
protected Hub();
public IHubCallerConnectionContext<dynamic> Clients { get; set; }
public HubCallerContext Context { get; set; }
public IGroupManager Groups { get; set; }
public void Dispose();
public virtual Task OnConnected();
public virtual Task OnDisconnected(bool stopCalled);
public virtual Task OnReconnected();
protected virtual void Dispose(bool disposing);
}
}

view raw
Hub.cs
hosted with ❤ by GitHub

Desde el lado del cliente los métodos estarán disponibles en el código JavaScript generado por SignalR. Veremos dichos métodos en detalle en cada evento en cuestión, junto con la explicación de cada uno:

Seguir leyendo “Eventos de conexión en SignalR”

Grupos en SignalR: administración y opciones de comunicación

En el post anterior vimos las distintas formas que tenemos disponibles en SignalR para poder comunicarse con los clientes de la aplicación, siendo los grupos la forma más completa y compleja, y por lo tanto merecedora de su propio post 😉

Los grupos nos permiten concentrar varios clientes a través de un identificador global, lo cual nos permite poder comunicarnos con los mismos a demanda sin preocuparnos por los clientes en sí que están en el grupo, más allá del momento en el cual lo creamos. Esto nos permite separar la responsabilidad del uso de grupos en dos partes: administrar los grupos y comunicarse con los clientes que los componen.

Administrando los grupos

Comencemos por el primer punto, cómo crear un grupo y agregarle como integrante un cliente? Ambas cosas se hacen directamente en un mismo método, como se puede ver a continuación:

/// <summary>
/// Une al cliente al grupo especificado.
/// </summary>
/// <param name="groupName">Nombre del grupo.</param>
public void JoinToGroup(string groupName)
{
Groups.Add(Context.ConnectionId, groupName);
}

view raw
SignalR-AddGroup.cs
hosted with ❤ by GitHub

En el Hub de SignalR tenemos disponible el elemento Groups (al igual que Clients) sobre el cual podemos ejecutar la operación Add. En la misma deberemos pasar dos parámetros, el ConnectionId del cliente que queremos agregar al grupo y el nombre/identificador del mismo. Lo que pasará aquí internamente es que si no existe el grupo con el nombre indicado se creará el mismo y luego agregará el cliente. Cabe destacar que un cliente puede estar en todos los grupos que se requiera, o en ninguno.

Seguir leyendo “Grupos en SignalR: administración y opciones de comunicación”

Opciones para comunicarse con los clientes en SignalR

Continuando con los post’s asociados a SignalR, ya hemos podido ver tanto la implementación de SignalR dentro de ASP.NET MVC cómo el concepto del ConnectionId para identificar de forma unívoca a un cliente. Sobre esto último hemos mencionado que en las formas de envío más avanzadas de SignalR se debe hacer uso de este valor.

Veamos cuales son las formas de conexión a clientes que tenemos disponibles desde el servidor hacia los clientes:

Broadcast:

Para mi esta es la forma más sencilla de enviar notificaciones, ya que se las enviamos a absolutamente todos los clientes conectados a nuestra aplicación sin necesidad de conocer quienes son.

Este es el ejemplo que venimos usando desde el primer post asociado a la implementaciónel primer post asociado a la implementación. Para hacer uso de esta opción el Hub usaremos el elemento Clients con la opción All, indicando luego la operación del lado del cliente que queremos invocar:

namespace NotificationApp.Hubs
{
using Microsoft.AspNet.SignalR;
/// <summary>
/// Hub de notificaciones de la aplicación.
/// </summary>
public class NotificationHub : Hub
{
/// <summary>
/// Acción de notificación de una tarea completa.
/// </summary>
/// <param name="taskId">Identificador de la tarea.</param>
/// <param name="taskResult">Resultado de la tarea.</param>
public void Notificate(int taskId, bool taskResult)
{
Clients.All.markDone(taskId, taskResult);
}
}
}

view raw
NotificationHub.cs
hosted with ❤ by GitHub

Seguir leyendo “Opciones para comunicarse con los clientes en SignalR”