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

19 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!
martes, 22 de enero de 2019

Blogger invitado

Blogger invitado

Jorge Turrado

Apasionado de la programación, siempre buscando la manera de mejorar el día a día con el desarrollo de tecnologías .NET. Apasionado de este momento tan cambiante y fabuloso para ser desarrollador C#.
Blog: Fixed Buffer
Hola a todos los lectores de Variable Not Found, es un gusto para mi poder hacer esta colaboración con José, en la que vengo a hablaros de cómo poder utilizar código nativo desde .NET Core, sin perder la capacidad de ejecución multiplataforma que nos ofrece este maravilloso framework.

¿Y por qué me debería interesar utilizar código nativo si .NET Core ya es lo bastante rápido? Esa es una muy buena pregunta, es cierto que con .NET Core y su filosofía cloud se ha mejorado muchísimo el rendimiento, y se ha modularizado el framework consiguiendo unos resultados muy buenos.

Sin embargo, imagina que tu aplicación web necesita de un rendimiento excelente, por ejemplo, porque necesites enviarle imágenes y tengas que procesarlas en el servidor para leer un OCR o procesar su contenido. En estos casos, cada ciclo cuenta, ya que afecta directamente a la escalabilidad de tu aplicación; no es lo mismo tardar 10 milisegundos que 20, cuando hablas de un gran número de usuarios concurrentes.

El framework nos da la posibilidad de ejecutar código nativo (ya .NET Framework nos daba esa posibilidad hace mucho), pero el código nativo es código compilado directamente para el sistema operativo, y esto hace que una librería de Windows sólo sirva para Windows, lo mismo que si fuese de Linux o MacOS.

Hoy vamos a abordar ese problema, creando librerías nativas multiplataforma, que podamos compilar sin tener que cambiar nada en ellas (lo cual nos permite tener una única librería que mantener) y consumiéndolas desde .NET Core. Por eso, en mi blog FixedBuffer he dejado la primera parte de esta entrada:

Crear y utilizar librerías multiplataforma con C++ y .NET Core (Parte 1)

A partir de aquí, vamos a considerar que ya tenéis vuestra librería nativa compilada, y vamos a centrarnos solo en la parte de C# y .NET Core.

lunes, 21 de enero de 2019
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 15 de enero de 2019
ASP.NET Core Como sabemos, los archivos Razor _ViewImports.cshtml y _ViewStart.cshtml se emplean para introducir directivas y código de inicialización para todas las vistas o páginas que se encuentren por debajo en la estructura de carpetas del proyecto.

Es decir, si el archivo _ViewImports.cshtml se encuentra en la carpeta /Views, todas las vistas que hay por debajo heredarán las directivas que hayamos especificado en su interior, de la misma forma que /Pages/_ViewImports.cshtml afectara a las páginas presentes en la carpeta /Pages y descendientes.

Pues bien, hace unos días, un alumno del curso de ASP.NET Core en CampusMVP (que, por cierto, ha sido recientemente actualizado a la versión 2.2 del framework) planteaba una duda sobre un escenario algo más complejo. Si una aplicación tenía vistas en la carpeta /Views, también tenía vistas en áreas (carpeta /Areas), e incluso pudiera tener algunas páginas Razor en /Pages, la pregunta era si existía algún mecanismo para hacer que todas las vistas o páginas definidas en dichas carpetas compartieran directivas (como using o importaciones de tag helpers) sin tener que duplicar este código en sus respectivos _ViewImports.cshtml para cada una de ellas.

A priori pensé que quizás el planteamiento sería retocar ligeramente el motor de vistas, pero, tras estudiarlo un rato, vi que el tema era mucho más sencillo :)
lunes, 14 de enero de 2019
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

miércoles, 9 de enero de 2019
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 8 de enero de 2019
Top Posts 2018 en Variable Not Found Desde hace una década, el primer post de enero siempre lo reservo para revisar qué publicaciones del blog han sido las más visitadas del año recién finalizado, así que vamos a continuar con esta arraigada tradición una vez más ;)

También, como no podía ser de otra forma, aprovecho también para desearos a todos un año 2019 lleno de alegrías tanto en el terreno personal como en el profesional, deseo que podéis considerar extensible para a todos los que os rodean y os importan :)

Y dicho esto, vamos al tema...
viernes, 28 de diciembre de 2018
.NET Core Desde que apareció Roslyn, C# ha ido evolucionando a pasos agigantados. Tanto es así que es frecuente encontrar desarrolladores que, aunque lo usan a diario, desconocen todo su potencial porque la velocidad de introducción de cambios en el lenguaje es mayor que la de asimilación de novedades por parte de los profesionales que nos dedicamos a esto.

Por ejemplo, en las consultorías técnicas que realizo en empresas es frecuente encontrar equipos de trabajo en los que aún no está generalizado el uso de construcciones tan útiles como el null coalescing operator (fullName ?? "Anonymous"), safe navigation operator (person?.Address?.Street), el at object operator (Address@person), o características tan potentes como las funciones locales, interpolación de cadenas, tuplas o muchas otras.

Sin embargo, creo que el rey de los desconocidos es el operador virgulilla "~" de C#. Introducido con C#7 es probablemente uno de los operadores menos utilizados y, sin embargo, de los más potentes ofrecidos por el lenguaje.
Nota de traducción: el nombre original del operador es "tilde operator", y como he encontrado poca literatura al respecto en nuestro idioma, me he tomado la libertad de traducirlo como operador virgulilla (¡sí, esa palabra existe!). También, en entornos más informales lo encontraréis con el nombre "wormy operator" (operador gusanillo) o como "soft similarity operator" (que podríamos traducir como operador de similitud relajada).
lunes, 24 de diciembre de 2018
Enlaces interesantes, edición feliz navidad! Ahí van los enlaces recopilados durante la semana pasada y, como siempre, espero que os resulten interesantes :-)

Y de paso, aprovecho este momento  para desearos a todos unas felices fiestas y un grandioso 2019 en todos los ámbitos.

Por si te lo perdiste...

.NET / .NET Core

martes, 18 de diciembre de 2018
ASP.NET Core MVC Hace unos días publicaba un post sobre la mala idea que era tener controladores con demasiadas responsabilidades y cómo un constructor con demasiadas dependencias podía ser una señal (un 'code smell') de que las cosas no estaban yendo bien en ese sentido.

Por ejemplo, echando un vistazo al siguiente controlador podemos ver claramente una violación del Principio de Responsabilidad Única (SRP) en un controlador que conoce demasiados detalles sobre la forma de proceder al registrar un pedido:
public class OrderController: Controller
{
    private readonly IOrderServices _orderServices;
    [...] // Other private members

    public OrderController(IOrderServices orderServices, IUserServices userServices, 
        IMailingService mailingServices, ISmsServices smsServices, 
        IPdfGenerator pdfGenerator, IMapper mapper
    )
    {
        _orderServices = orderServices;       
        _userServices = userServices;
        [...] // Other assignments...
    }

    [HttpPost]
    public Task<IActionResult> Submit(OrderViewModel orderViewModel)
    {
        if(!ModelState.IsValid)
        {
            return View(orderViewModel);
        }
        var orderDto = _mapper.Map<OrderDto>(orderViewModel);
        var orderResult = await _orderServices.AddAsync(orderDto);
        if(!orderResult.Success)
        {
            return RedirecToAction("OrderError", new { error = orderResult.Error }));
        }
        var userPreferences = await _userServices.GetNotificationPreferencesAsync(CurrentUserId);
        var pdfUrl = await _pdfGenerator.GenerateOrderAsync(orderResult.Details);
        if(userPreferences.NotificationMode == NotificationMode.Sms)
        {
            await _smsServices.NotifyNewOrderAsync(orderResult.Details, pdfUrl);
        } 
        else 
        {
            await _mailingServices.NotifyNewOrderAsync(orderResult.Details);
        }
        return RedirectToAction("ThankYou", new { id = orderResult.Details.OrderId } );
    }
    ...
}
En dicho post comentaba también algunas cosas que podíamos hacer para solucionar el problema, así como una recomendación de lo que no debíamos hacer: disimular dependencias instanciando directamente componentes o utilizando otros "sabores" de inyección que hicieran menos evidente la relación de nuestra clase con otras de las que depende.

Pues bien, como hoy estamos algo rebeldes, vamos a ver las técnicas que nos permitirían hacerlo cuando sea necesario o, dicho de otra forma, qué alternativas tenemos para usar dependencias desde los controladores sin que estas sean suministradas mediante inyección en su constructor.
Precaución: estas técnicas son consideradas antipatrones o, como mínimo, code smells en la mayoría de los escenarios, así que usadlas poco, con precaución y siempre con conocimiento de causa ;)
lunes, 17 de diciembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 11 de diciembre de 2018
La pasada semana, en el contexto del evento Microsoft Connect(); 2018, se lanzaron las últimas versiones de la familia de productos "Core": .NET Core 2.2, ASP.NET Core 2.2 y Entity Framework Core 2.2.

En todos los casos son revisiones pequeñas y que no rompen nada de lo anterior, pero en cada uno de estos productos se han introducido mejoras que vale la pena conocer, por lo que, antes que nada, os recomiendo que echéis un vistazo a los artículos anteriores, que son los anuncios oficiales.

En este post vamos a ver rápidamente las novedades más destacables de ASP.NET Core 2.2.
lunes, 10 de diciembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

lunes, 3 de diciembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 27 de noviembre de 2018
Desarrolladores Como sabemos, la inyección de dependencias está grabada a fuego en los genes de ASP.NET Core. La mayoría de sus componentes la usan internamente para obtener acceso a otros componentes que necesitan para cumplir sus funciones y, además, es una práctica recomendada en la parte que nos toca a nosotros como desarrolladores de aplicaciones.

Por ello, en ASP.NET Core MVC, lo habitual es que implementemos nuestros controladores atendiendo a este principio, y para ello utilicemos la técnica de inyección de dependencias en el constructor:
public class InvoiceController: Controller
{
    private readonly IInvoiceServices _invoiceServices;
    private readonly IMapper _mapper;
    private readonly ILogger<InvoiceController> _logger;

    public InvoiceController(
        IInvoiceServices invoiceServices, 
        ILogger<InvoiceController> logger,
        IMapper mapper)
    {
        _invoiceServices = invoiceServices;
        _logger = logger;
        _mapper = mapper;
    }
    ...
}
Nota: aunque en este post estemos hablando de controladores ASP.NET Core MVC, las ideas que vamos a comentar aquí son también aplicables a ASP.NET MVC "clásico" e incluso a otro tipo de frameworks que comparten los mismos conceptos.
lunes, 26 de noviembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada, algo más escasa de lo habitual debido a los festivos en USA. Pocos, pero espero que interesantes :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 20 de noviembre de 2018
ASP.NET Core MVC Seguramente habréis notado que en proyectos ASP.NET Core 2.1 la compilación de las vistas funciona de forma ligeramente diferente a como se hacía en versiones anteriores. Hasta ahora las vistas sólo eran compiladas al publicar el proyecto pero, a partir de esta versión, este proceso se realizará antes, durante la compilación.

En este artículo vamos a ver cómo aprovechar las ventajas de la precompilación, y al mismo tiempo mantener la flexibilidad que nos ofrece la compilación en tiempo de ejecución que tradicionalmente hemos disfrutado en proyectos ASP.NET y ASP.NET Core.

lunes, 19 de noviembre de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 13 de noviembre de 2018
ASP.NET Core MVCEn el post anterior veíamos cómo personalizar los mensajes de error generados durante el proceso de binding, y cómo aprovechar las posibilidades que nos brinda el framework para introducir textos localizados en esos puntos.

Hoy seguiremos profundizando en este tema, pero esta vez nos centraremos en modificar los textos por defecto de las anotaciones de datos y hacer que simplemente decorando una propiedad con un atributo como Required consigamos obtener mensajes de error localizados y a nuestro gusto, sin necesidad de establecer el ErrorMessage de forma explícita y, en algunos casos, ni siquiera tener que indicar dicho atributo.
lunes, 12 de noviembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 6 de noviembre de 2018
ASP.NET Core MVCEn el framework ASP.NET Core MVC es muy sencillo establecer los mensajes de error de validación de campos utilizando propiedades de las data annotations, como en el siguiente ejemplo:
namespace LocalizationDemo.ViewModels
{
    public class PersonViewModel
    {
        [Required(ErrorMessage ="The name is required")]
        public string Name { get; set; }
    }
}
Incluso es bastante fácil hacer que este texto aparezca traducido atendiendo a la cultura del hilo actual. Para ello, simplemente debemos configurar los servicios de localización apropiadamente, e indicar en la propiedad ErrorMessage la clave del mensaje de error en el archivo RESX asociado a la clase:
// En Startup.cs:
public void ConfigureServices()
{
    ...
    services.AddLocalization(opt=>opt.ResourcesPath="Resources");
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddViewLocalization()
        .AddDataAnnotationsLocalization(); // Esta línea añade la localización 
                                           // de data annotations 
    }

// En el view model:
namespace LocalizationDemo.ViewModels
{
    public class PersonViewModel
    {
        // El mensaje de error está definido 
        // en Resources/ViewModels.PersonViewModel.resx
        [Required(ErrorMessage ="NameIsRequired")] 
        public string Name { get; set; }
    }
}
Esto es así de fácil para las validaciones que declaramos de forma explícita en nuestro código, mediante atributos de anotaciones de datos. Sin embargo, existen otro tipo de validaciones que se realizan de forma implícita (por ejemplo, cuando en un campo entero introducimos un valor no numérico) y cuyos mensajes de error no son tan sencillos de establecer.
lunes, 5 de noviembre de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

lunes, 29 de octubre de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

martes, 23 de octubre de 2018
ASP.NET Core MVC Desde que comenzamos a programar con ASP.NET MVC tenemos interiorizado que si en nuestras acciones vemos código repetido, suele ser un candidato a ser implementado en forma de filtro. Así, durante años hemos implementado en forma de action filters asuntos transversales de nuestras aplicaciones, como la seguridad, logging, caching y otros aspectos.

Sin embargo, a veces olvidamos que estas mismas técnicas podemos utilizarlas para simplificar código en la implementación de convenciones o funciones más ligadas al negocio o a funcionalidades de nuestra aplicación. Por ejemplo, ¿no estáis aburridos de escribir acciones como las siguientes?
public class FriendsController: Controller
{
    public IActionResult View(int id) 
    {
        var friend = _friendServices.GetById(id);
        if(friend == null)
           return NotFound();
        ... // Prepare and show "View" view
    }

    public IActionResult Edit(int id) 
    {
        var friend = _friendServices.GetById(id);
        if(friend == null)
           return NotFound();
        ... // Prepare and show "Edit" view
    }

    public IActionResult Delete(int id) 
    {
        var friend = _friendServices.GetById(id);
        if(friend == null)
           return NotFound();
        ... // Prepare and show "Delete" view
    }

    ...
}
Pues bien, vamos a aplicar el mismo principio para simplificar este código y eliminar duplicidades extrayendo las porciones comunes a un filtro, resultando en algo así de bonito:

[Autoload(typeof(Friend))] // ¡Magia!
public class FriendsController: Controller
{
    public Task<IActionResult> View(Friend friend) 
    {
        ... // Prepare and show "View" view
    }

    public Task<IActionResult> Edit(Friend friend) 
    {
        ... // Prepare and show "Edit" view
    }

    public Task<IActionResult> Delete(Friend friend) 
    {
        ... // Prepare and show "Delete" view
    }
    ...
}
No sé lo útil que podrá resultar en la práctica pero, como mínimo, nos ayudará a conocer mejor cómo funciona por dentro el framework ASP.NET Core MVC.
lunes, 22 de octubre de 2018
Enlaces interesantes Después del parón de la semana pasada debido a compromisos profesionales (¡hola, chic*s!), continuamos con una nueva recopilación de enlaces que, como siempre, espero que os resulten interesantes :)

Por si te lo perdiste...

.NET / .NET Core

martes, 9 de octubre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

.NET timeline
martes, 2 de octubre de 2018
¿Qué podría salir mal? Pues como uno que os habla, seguro que muchos de vosotros habéis comparado miles de veces si un objeto es nulo utilizando un patrón de código C# como el siguiente:
var invoice = _invoiceRepository.GetById(18);
if(invoice == null) 
{
    // Hacer algo
}
¿Qué podría salir mal, verdad?

Pues aunque pueda parecer raro, hay casos en los que la comparación anterior no funcionaría bien... o mejor dicho, no funcionaría como esperamos.

Hace unos días leía un post de Khalid Abuhakmeh en el que hacía referencia a una charla de Channel 9 en la que Mads Torgersen recomendaba no utilizar la doble igualdad para comparar con null (minuto 33:00, aprox.)

lunes, 1 de octubre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste:

.NET / .NET Core

martes, 25 de septiembre de 2018
ASP.NET Core MVC Hace unos días, un alumno del curso online de ASP.NET Core en CampusMVP (por cierto, desde hace unas semanas actualizado a la versión 2.1) me planteaba una cuestión que quizás podría interesar a alguien más, por lo que vamos a comentarla por aquí.

Básicamente, la duda era la siguiente:
¿Hay alguna forma sencilla de añadir el atributo [Authorize], pero sólo a los controladores que se encuentren en una carpeta determinada del proyecto, sin tener que aplicarlo uno a uno?
La respuesta rápida es: sí. Bueno, con matices ;) Incluso hay varias opciones, así que vamos a ver algunas de ellas, y de paso repasamos conceptos de ASP.NET Core MVC :)
lunes, 24 de septiembre de 2018
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste:

.NET / .NET Core

martes, 18 de septiembre de 2018
Tools Los que peinamos ya bastantes canas recordamos con nostalgia aquellas intensas sesiones de programación intentando arañar ciclos de CPU y bytes en nuestro flamante Spectrum para sacar el máximo provecho de, en el mejor de los casos, un Zilog Z80A a 3,5MHz con 48K de memoria RAM. ¡Ah, el maravilloso mundo de las micro-optimizaciones!

Hoy en día, salvo en contadas ocasiones, ha dejado de tener sentido invertir demasiado tiempo en estas labores. Tenemos máquinas potentes, con micros cuya velocidad se mide en GHz capaces de ejecutar bastantes tareas de forma concurrente, y muchos Gigabytes libres de memoria RAM en los que guardar información. Además, los frameworks actuales como .NET permiten despreocuparse de asuntos como la reserva o liberación de memoria porque ya hay sistemas de más bajo nivel que se encargan de eso por nosotros.

Indudablemente es un gran avance, pero esto ha llevado a que, con el tiempo, se nos esté atrofiando ese sentido arácnido que antes nos disparaba las alertas cuando cierto código podía ser optimizado para consumir menos recursos.

En la mayoría de escenarios, y sobre todo cuando trabajamos en entornos empresariales, aplicaciones de escritorio o webs de poca carga, está bien así. Sin embargo, es cierto también que las necesidades han cambiado.

Por ejemplo, ahora creamos frecuentemente aplicaciones mucho más complejas que pueden ser utilizadas a través de Internet por miles de usuarios de forma simultánea y todos ellos esperan respuestas rápidas. Estas aplicaciones se ejecutan en servidores cuyos recursos son compartidos entre todos los usuarios que pueden llegar a tener un coste importante y debemos exprimir al máximo. Aquí, y en otros escenarios similares, es donde aparece de nuevo la necesidad de introducir optimizaciones en el código.

En este post vamos a hacer una introducción al uso de BenchmarkDotNet, una magnífica herramienta que nos permitirá medir el rendimiento de nuestro código .NET para hacerlo más eficiente en términos de uso de procesador y memoria.

Pero antes de empezar, no olvidéis la famosa frase de Donald Knuth:
“Los programadores consumen una gran cantidad de tiempo pensando, o preocupándose, sobre la velocidad de partes no críticas de sus programas, y esos intentos de mejorar la eficiencia tienen posteriormente un gran impacto negativo sobre la facilidad de depuración o mantenimiento. Deberíamos olvidarnos de las pequeñas mejoras de eficiencia, digamos en un 97% de los casos: la optimización prematura es el origen de todos los males. Sin embargo, no debemos dejar pasar la oportunidad de mejorar ese crítico 3% restante”
lunes, 17 de septiembre de 2018
Enlaces interesantes ¡Hola de nuevo! Pues sí, tras una larga temporada de descanso, por fin estamos de vuelta, preparados para la nueva temporada y con las baterías cargadas al 99% (ese 1% me temo que es ya irrecuperable ;D)

Y para celebrarlo, nada mejor que un buen puñado de enlaces recopilados durante la semana pasada que, como siempre, espero que os resulten interesantes. :-)

.NET / .NET Core

jueves, 12 de julio de 2018
Pues eso, que parecía que no llegaba y las semanas se hacían cada vez más cuesta arriba, pero por fin es el momento de descansar un poco e intentar conseguir un merecido reinicio mental.

Durante las próximas semanas dejaré el blog a merced de las olas, pues estaré disfrutando con la familia en las maravillosas playas de Cádiz: sol, paseos, refrescantes bañitos en las aguas del Atlántico y chiringuitos playeros con aroma a pescado fresco. Un buen plan, sin duda ;)

Costa Ballena, Cádiz
Imagen original

Nos vemos a la vuelta, ya en el mes de septiembre, con la batería al 100% y listos para seguir buscando la variable ;)

¡Felices vacaciones a todos!

Publicado con ánimo vacacional en Variable not found.
martes, 10 de julio de 2018
ASP.NET Core MVCLos que lleváis tiempo programando APIs HTTP, ya sea con ASP.NET Core o con otras tecnologías, seguro que en muchas ocasiones habéis tenido que decidir cómo retornar al cliente, de forma más o menos normalizada, los errores producidos en el lado servidor.

Lo habitual es echar mano de los status code de HTTP para indicar problemas en el proceso de una petición; de hecho, este protocolo dispone de un rico conjunto de códigos que en principio parecen cubrir todas nuestras necesidades.

Pero no siempre es así. Por ejemplo, si tenemos un servicio que permite a los clientes de una empresa formalizar un pedido a través de un API y una llamada a este servicio retorna un error HTTP 403 (forbidden), claramente estamos indicando que el solicitante no tiene permisos para hacer un pedido. Sin embargo, no tenemos una forma clara de indicar cuál es la causa de esta prohibición (¿quizás las credenciales no son correctas? ¿o quizás el cliente no tiene crédito en la empresa? ¿o puede ser que el administrador lo haya denegado expresamente?)

Para aportar más detalles sobre el problema, normalmente necesitaremos retornar en el cuerpo de la respuesta información extra usando estructuras o formatos personalizados, probablemente distintos de una aplicación a otra, y documentarlos apropiadamente para que los clientes puedan entenderlos. Y aquí es donde entra en juego el estándar “Problem details”.
lunes, 9 de julio de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET / .NET Core

martes, 3 de julio de 2018
ASP.NET Core MVC Uno de los objetivos de ASP.NET Core ha sido siempre servir como infraestructura para la creación de servicios HTTP o APIs web, por lo que ya desde las primeras versiones se incluían funcionalidades específicamente diseñadas para facilitar esta tarea.

ASP.NET Core 2.1 continúa profundizando en esa línea e incluye entre sus novedades el nuevo atributo [ApiController], un decorador aplicable a controladores que los identifica como puntos de entrada de APIS, aplicando de forma automática una serie de convenciones bastante útiles a la hora de crear este tipo de componentes:
[ApiController]
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    ...
}
Fijaos que, a diferencia de ASP.NET Web API (.NET Framework), se ha optado por utilizar un atributo en lugar de emplear herencia (en aquél framework existía la clase ApiController).
A continuación veremos qué debemos tener en cuenta a la hora de aplicar este atributo a nuestros controladores y qué convenciones son las que estaremos asumiendo al utilizarlo.
lunes, 2 de julio de 2018
MVP Award En esta ocasión sólo quería compartir con vosotros la gran alegría que supone ser honrado de nuevo con el galardón Microsoft MVP por las contribuciones y aportaciones realizadas a la comunidad de desarrolladores a lo largo del año pasado.

Son ya ocho años consecutivos y debería haberme acostumbrado a este subidón de primeros de julio, pero, como no suelo ser consciente de que ha llegado el día de los nombramientos, sigo recibiendo el conocido email de nombramiento casi con la misma emoción que aquella primera vez en que me pilló completamente desprevenido.

Muchas gracias a todos vosotros, amigos y amigas de Variable not found, porque si estoy aquí es porque me habéis regalado vuestro incondicional apoyo durante todos estos años.

Muchas gracias también al equipo del programa MVP en Microsoft y, en particular, a nuestra querida MVP lead Cristina González, por el gran trabajo que realizan.

Muchas gracias todos los que dedicáis vuestro tiempo la comunidad, seáis MVP o no, porque hacéis posible que todos aprendamos y mejoremos un poco más cada día.

Y, por supuesto, muchas gracias también a mi mujer e hijas, Inma, Inmita y María, porque ellas son las que permiten, con su infinita paciencia y comprensión, que pueda dedicar a mi pasión por el software más de lo que estrictamente requieren mis obligaciones profesionales.

Aprovecho también para enviar mi enhorabuena a los MVP renovados recientemente, y un caluroso abrazo de bienvenida a los que lo han sido por primera vez (es un momento muy bonito, ¡disfrutadlo!)

Sólo espero estar a la altura de esta distinción, compartida con gente de todo el mundo a la que admiro tanto personal como profesionalmente, y entre los que me enorgullezco de contar con grandes amigos. Y ahora, con esta dosis extra de motivación, ¡a seguir trabajando!

Desarrollador supermotivado
Source: Giphy

Publicado en Variable not found.
martes, 26 de junio de 2018
ASP.NET Core Con ASP.NET MVC 5 y anteriores solíamos utilizar @helper para crear porciones de HTML reutilizables en el interior de nuestras vistas, tanto para conseguir un código más limpio como para abrazar el principio DRY (Don’t Repeat Yourself), tan frecuentemente apaleado en la capa de presentación.

Recordaréis que esta directiva permitía crear “funciones” en cuyo interior podíamos escribir código Razor (mezclando marcado y C#) que podía ser invocado desde distintos puntos:
@* File: Test.cshtml *|

@Multiplication(2)
@Multiplication(3)

@helper Multiplication(int x)
{
    <h2>Multiplication table of @x</h2>
    <ul>
        @for (var i = 1; i <= 10; i++)
        {
            <li>@x * @i = @(x * i)</li>
        }
    </ul>
}
Además de definirlos y consumirlos desde la misma vista, también era posible crear helpers globales introduciéndolos en App_Code, aunque esta opción me gustaba menos y creo que no la utilicé jamás en aplicaciones reales.
Pues bien, por algunas extrañas razones, en ASP.NET Core la directiva @helper no está disponible, lo que puede complicarnos un poco a la hora de portar vistas antiguas o, simplemente, cuando queramos usarla para mejorar la legibilidad de nuestro código.
lunes, 25 de junio de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET / .NET Core

martes, 19 de junio de 2018
ASP.NET Core MVC Como sabéis, por defecto las acciones MVC y Web API en ASP.NET Core retornan un IActionResult (o un Task<IActionResult> en caso de ser asíncronas). Este interfaz, cuya única misión es definir el método de ejecución asíncrona del resultado, ExecuteResultAsync(), es implementado por la gran variedad de tipos de resultado ofrecidos de serie por el framework, como ViewResult, RedirectResult o FileResult.

Sin embargo, no es esta la única opción disponible a la hora de especificar el resultado de una acción, como veremos a continuación.
lunes, 18 de junio de 2018
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET / .NET Core