Como recordaréis, se trata de una mejora en el módulo ASP.NET Core (ANCM) que hace que las aplicaciones se ejecuten directamente dentro del worker del servidor web (w3wp.exe), evitando las llamadas internas producidas cuando IIS actuaba como un mero proxy inverso.
Por verlo gráficamente, el siguiente diagrama muestra la arquitectura tradicional de un sistema ASP.NET Core funcionando sobre IIS. En el modelo out-of-process utilizado hasta ASP.NET Core 2.1, cada petición realizada desde el exterior era capturada por IIS, que a su vez lanzaba una petición HTTP local con los mismos contenidos hacia Kestrel, que era quien la procesaba ejecutando nuestro código. La respuesta generada desde Kestrel era enviada de vuelta a IIS como respuesta a la petición, quien la retornaba al agente de usuario:

En este modelo de funcionamiento, por tanto, cada petición HTTP entrante generaba otra petición HTTP interna que, aunque estuviera dentro de la misma máquina, imponía una penalización importante en el rendimiento de las aplicaciones.
El hosting in-process, aparecido con ASP.NET Core 2.2, cambia las reglas del juego eliminando esas peticiones HTTP internas y los retardos que implicaban, lo que ha posibilitado el espectacular incremento en el rendimiento que su uso ofrece. Ahora, el módulo para IIS ejecuta internamente la aplicación y se comunica con ella de forma directa:

Este es el modo por defecto de los nuevos proyectos ASP.NET Core creados usando las plantillas estándar, algo que podemos claramente ver si echamos un vistazo al archivo
.csproj
de un proyecto recién creado, ya sea desde Visual Studio o desde .NET Core CLI: <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
Si tenéis un proyecto ASP.NET Core 2.1 o anterior y lo actualizáis a 2.2, tendréis que añadir el elemento <AspNetCoreHostingModel>
de forma manual para usar este modelo de ejecución.
Sin embargo, estas mejoras espectaculares no son gratis del todo, y creo que es interesante conocer un poco mejor lo que implica asumir este nuevo modo de funcionamiento de nuestras aplicaciones y responder a algunas preguntas que podríamos hacernos por el camino.Publicado por José M. Aguilar a las 8:40 a. m.
Etiquetas: aspnetcore, aspnetcoremvc
Por si te lo perdiste...
- Cómo incluir scripts en la página desde vistas parciales ASP.NET Core MVC con DynamicSections
José María Aguilar - 7 Hábitos de personas altamente innovadoras
José María Aguilar
.NET / .NET Core
- Crear y utilizar librerías multiplataforma con C++ y NetCore (Parte 1)
Jorge Turrado - What Was New for .NET Developers in 2018 & the Road Ahead
Damir Arh - C# – Why you should never use the checked keyword – Unless absolutely necessary
John Demetriou - “Stack Walking” in the .NET Runtime
Matt Warren - Writing a language-agnostic Roslyn Analyzer using IOperation
Gérald Barré - WasmWinforms: C# Winforms for Webassembly
Roozbehid - Switch to errors instead of warnings for nullable reference types in C# 8
Jiří Činčura - Weirdness with EF Core 2 (SQLite), .NET Standard, and .NET Framework
Jeremy Clark - C# .NET Core vs Java - Which programs are faster?
The Benchmarks game - COM Object Access and dynamic in .NET Core 2.x
Rick Strahl - C#’s discards don’t need var
Jiří Činčura - Correctly reading encoded text with the StreamReader in .NET
Jeremy Lindsay - .NET Core tooling update for Visual Studio 2019 Preview 2
Phillip Carter - ThreadPool.QueueUserWorkItem has a generic overload (and a new parameter)
Jiří Činčura - Do more with patterns in C# 8.0
Mads Torgersen - The Ultimate List of .NET Dependency Injection Frameworks
Claudio Bernasconi - C# Deadlocks in Depth – Part 2
Michael Shpilt
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#.¿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.
Publicado por José M. Aguilar a las 10:00 a. m.
Etiquetas: c++, colaboraciones, jorgeturrado, netcore
Por si te lo perdiste...
- Redirecciones HTTP 303, 307 y 308: ¿las conoces?
José María Aguilar - 13 Consejos para comentar tu código
José María Aguilar
.NET / .NET Core
- More DI: Unit Testing Async Methods
Jeremy Clark - Migrating from .NET to .NET Standard
Rockford Lhotka - .NET Standard and Multi-targeting
Corrado Cavalli - Monitoring GC and memory allocations with .NET Core 2.2 and Application Insights
Stefán Jökull Sigurðarson - JSON Web Encryption (JWE) in .NET Core
Scott Brady - System.Data in .NET Core 3.0
Jonathan Allen - Interpolated verbatim string in C# 8
Jiří Činčura - Delegate, predicate, Action, Func, métodos anónimos, explicados para mortales
Leo Micheloni - Stopping Garbage Collection in .NET Core 3.0 (part I)
Luca Bolognese - Performance Tuning for .NET Core
Reuben Bond - Managed pointers in .NET
Konrad Kokosa - Code Contracts: A Technique to Cut Down on Bugs
Carlos Schults - When Will JustMock Support .NET Core? Right Now!
Mihail Vladov - Using Background Intelligent Transfer Service (BITS) from .NET
Peter Smith - C# 8: Type Inference for the New Keyword & Caller Expression Attribute for Assertions and Automated Testing & Generic Attributes
Jonathan Allen - C# Deadlocks in Depth - Part 1
Michael Shpilt
_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 :)
Por si te lo perdiste...
- Extendiendo claims de usuarios en ASP.NET Core
José María Aguilar - Problemas al comentar el código fuente
José María Aguilar
.NET / .NET Core
- .NET Core January 2019 Updates – 2.1.7 and 2.2.1
Lee Coward - Codez: A Random String Generator and Why I Wrote It
Khalid Abuhakmeh - Rendering Markdown to HTML and Parsing YAML Front Matter in C#
Mark Heath - Do we need JVM’s PhantomReference in .NET?
Konrad Kokosa - Implementing Phantom Reference in C#
Oren Eini - Implementing Java ReferenceQueue and PhantomReference in C#
Kévin Gosse - Collectible assemblies in .NET Core 3.0 | StrathWeb. A free flowing web tech monologue.
Filip Woj - Announcing ML.NET 0.9 – Machine Learning for .NET
César de la Torre - Profiling Concurrent .NET Code with BenchmarkDotNet and visualizing it with Concurrency Visualizer
Adam Sitnik - Deep-dive into .NET Core primitives, part 3: runtimeconfig.json in depth
Nate McMaster
Por si te lo perdiste...
- Renderizar una vista Razor a un string en ASP.NET Core MVC
José María Aguilar - Top posts 2017 en Variable not found
José María Aguilar
.NET / .NET Core
- Generate automatically async/await code from sync code with Roslyn
Alexandre Mutel - Background jobs in ASP.NET Core made easy with Hangfire
Matthew D. Groves - How to parse a high rate stream of data with low memory allocation
Riccardo Terrell - Comparing RestSharp and Flurl.Http while consuming a web service in .NET Core
Jeremy Lindsay - Less commonly used C# operators
Damir Arh - SOLID Principles in C# - Open Closed Principle
Marinko Spasojevic - Build your first .NET Core 3.0 application in Linux
Anuraj Parameswaran - Implement Observer Pattern in .NET (3 Techniques)
Chinmoy Mohanty - String Interpolation Functions vs. string.Format Constants
Scott Hannen - Using Polly and Flurl to improve your website
Jeremy Lindsay - Image Classification Using Keras
James McCaffrey - Accessibility of nested classes
Eric Lippert - Find, Fix, and Avoid Memory Leaks in C# .NET: 8 Best Practices
Michael Shpilt

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

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

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...
- Xmas Tree scan, el escaneo de puertos navideño
José María Aguilar - Constantes string multilínea en C#
José María Aguilar
.NET / .NET Core
- .NET Core - What's Coming in .NET Core 3.0
Scott Hunter - Composing Honest Methods in C#
Yacoub Massad - Comparaciones en C#
Eduard Tomás - ClosedXML, una manera fácil de dar formato a nuestros .xlsx
Jorge Turrado - VB.NET Hits High in Programming Language Popularity Index
David Ramel - Enable repeatable package restores using a lock file
Anand Gaurav - Garbage Collection in C# (.NET Framework and .NET Core)
Damir Arh - Writing a Roslyn analyzer
Gérald Barré - The Lazy applicative functor
Mark Seemann - Interesting uses of tuple deconstruction
Nigel Sampson - C# All The Things
David Pine - Presenting HttpTracer Library
Daniel Causer - How to Remove Application Insights
Matt Watson - C# Features: An Exhaustive List of the Best Ones
Carlos Schults - Updating Westwind.AspnetCore.Markdown with Markdown from Files and URLs
Rick Strahl - Top .NET Tutorials in 2018
David Ramel
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 ;)
Por si te lo perdiste...
- Leyes epónimas relacionadas con el desarrollo de software (y II)
José María Aguilar - 10 razones por las que tu blog te ayuda a encontrar empleo
José María Aguilar
.NET / .NET Core
- Seven reasons that Roslyn-based Code Analysers are awesome
Tom Wright - A Simple Look at .NET Memory Model
James M. Curran - Why is string.GetHashCode() different each time I run my program in .NET Core?
Andrew Lock - Six Opinionated Tips to be a Better .NET Developer
Isaac Levin - Writing xUnit Tests in .NET Core & Providing Constant Context for .NET Core Tests
Peter Vogel - Support for Value Objects in C#
Steve Smith - Explicit interface implementation
Ed Freeman - Announcing .NET Framework 4.8 Early Access Build 3707
Namrata Karnam - Exploring the .NET Core Runtime (in which I set myself a challenge)
Matt Warren
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.
Por si te lo perdiste...
- Leyes epónimas relacionadas con el desarrollo de software (I)
José María Aguilar - ¡Mi pantalla se ha puesto gris!
José María Aguilar
.NET / .NET Core
-
Announcing .NET Core 2.2
Rich Lander
-
Announcing .NET Core 3 Preview 1 and Open Sourcing Windows Desktop Frameworks
Rich Lander
-
Announcing WPF, WinForms, and WinUI are going Open Source
Scott Hanselman
-
C#: Conversiones (explícitas o implícitas) e interfaces
Eduard Tomás
-
Miscellaneous C# Async Tips
Stuart Lang
-
Explicitly Ignoring Exceptions in C#
Rick Strahl
-
Why does Clipboard.SetData put extra junk in the clipboard data? And how can I get it to stop?
Raymond Chen
-
C# Features: Innovations or Imitations? – Part 3
Michael Shpilt
-
Lecturas recomendadas sobre c# y .net · noviembre 2018
Albert Capdevila
-
HttpClientFactory .NET Core 2.1
Daniel Donbavand
-
Open Source .NET – 4 years later
Matt Warren
-
Announcing ML.NET 0.8 – Machine Learning for .NET
César de la Torre
-
Using Stopwatch and ContinueWith to Measure Task Execution Time in C#
Matthew Jones
-
Exploring C#’s ref return to better understand it
Jiří Činčura
-
Depuración remota sobre SSH
Jorge Turrado
-
Performance in .NET – Part 3
Ricardo Peres
-
An Ad Hoc Approach to Passing Elements from Blazor to JavaScript
Peter Vogel
-
Using Roslyn C# Completion Service programmatically
Filip Woj
Por si te lo perdiste...
- ¿Es mi biblioteca portable a .NET Core?
José María Aguilar - ¿Autoincrementos, incrementos o sumas?
José María Aguilar
.NET / .NET Core
- Announcing .NET Framework 4.8 Early Access build 3694
Namrata Karnam - Computer Controlled Watering System with C# or VB.NET
Troy Simpson - What happens if I mutate a string in a p/invoke?
Raymond Chen - Introducing the .NET Core Unit Testing Framework (or: Why xUnit?)
Peter Vogel - Working with the Dynamic Type in C#
Camilo Reyes - Elvis operator in expressions and why (probably) it’s not allowed
Jiří Činčura - Nifty trick: Combining constructor with collection initializer
Raymond Chen - Crear imágenes Docker de proyectos netcore en varias versiones del framework
Eduard Tomás - Taking advantage of the ordering guarantees of the LINQ GroupBy method
Raymond Chen - Creating a language server using .NET
Martin Björkström - Overcoming Limitations of .NET Core
Fiodar Sazanavets - Returning an XML Encoded String in .NET
Rick Strahl

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.
Publicado por José M. Aguilar a las 8:55 a. m.
Etiquetas: aspnetcoremvc, aspnetmvc, buenas prácticas, patrones
Por si te lo perdiste...
- ¿Se pueden desarrollar aplicaciones ASP.NET Core con Visual Basic .NET?
José María Aguilar - Entre 10 y 28 desarrolladores por el precio de uno
José María Aguilar
.NET / .NET Core
- Caching http requests to debug faster
Gérald Barré - AutoMapper 8.0.0 Released
Jimmy Bogard - How to use the Abstract Factory design pattern in C#
Gary Woodfine - Como instalar .NetCore en Linux
Jorge Turrado - Getting Stack Overflow Localization Tooling Ready for .NET Core
Samo Prelog - Accessing NuGet Package Paths in Your .NET SDK Based csproj Files
Georg Dangl - Java vs C# – Part 3
Ricardo Peres - Code reliability: Unit testing with XUnit and FluentAssertions in .NET Core 2 apps
Anthony Giretti - Introducing the ML.NET – A Machine Learning library for .NET developers
Coding Notes - Cómo buscar patrones de búsqueda o coincidencias en C# dentro de un bucle switch & Cómo buscar patrones de búsqueda o coincidencias en C# dentro de un bucle switch con C# 6.0 o anterior
Jorge Serrano - How to Choose the Right .NET Collection Class?
Damir Arh
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.
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Programación esotérica
José María Aguilar - Autenticación JWT en APIs con ASP.NET Core
José María Aguilar
.NET / .NET Core
- Building C# 8.0
Mads Torgersen - C#: Structs de un solo campo como typedefs
Eduard Tomás - .NET Core/ .NET Framework My Perspective On The Future
Mitchel Sellers - Cross-platform Time Zones with .NET Core
Christopher Roberts - .NET Core tooling update for Visual Studio 2017 version 15.9
Phillip Carter - Writing ILogger Diagnostics to a File
Christian Nagel - .NET Core 2.1.x será soportado hasta 3 años de la declaración TLS
Jorge Serrano - Some quick notes on converting String operations to use Span<T>
Matt Lacey - Handling a new era in the Japanese calendar in .NET
Ron Petrusha - Sample performance investigation using BenchmarkDotNet and PerfView
Adam Sitnik - A dynamic definite assignment puzzle
Eric Lippert - .NET Core Service Provider Gotchas and Less-Known Features
Ricardo Peres - Visual Basic in .NET Core 3.0
Kathleen Dollard
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.Por si te lo perdiste...
- El gran consejo para crear código mantenible
José María Aguilar - Probar scripts en producción sin desplegar nada, y otros usos interesantes de Fiddler
José María Aguilar
.NET / .NET Core
- Announcing .NET Standard 2.1
Immo Landwerth - Announcing ML.NET 0.7 (Machine Learning .NET)
César de la Torre - Understanding the Whys, Whats, and Whens of ValueTask
Stephen Toub - Rompiendo los limites: Mocking en las Pruebas Unitarias .Net
Jorge Turrado -
Move your first steps with .NET Core 3.0 for desktop development
Matteo Pagani - Smart enums / Type-safe enums in .NET
Gérald Barré - Exploiting multiplication by zero optimization (and failing), yet learning about equals to zero shortcut (Roslyn)
Jiří Činčura - Code Coverage is Finally Easy in .Net Core
Lee Richardson - dotnet-script 0.27.0 is out – with a ton of features!
Filip Woj - Creating a .NET Global Tool from an existing Console Application
Rick Strahl - An Early Exploration of Blazor
Dane Vinson - Creating your own (simple) dependency injection framework: Service Locator
Jonathan Donaldson
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.Publicado por José M. Aguilar a las 9:15 a. m.
Etiquetas: aspnetcore, aspnetcoremvc, localizacion, trucos
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Sabes 1337?
José María Aguilar - Personalizar las plantillas de controladores y vistas para ASP.NET Core MVC
José María Aguilar
.NET / .NET Core
- .NET Core Opinion - Be Wary of GUI Build Tools
K. Scott Allen - The future of JSON in .NET Core 3.0
Immo Landwerth - Announcing .NET Framework 4.8 Early Access build 3673
Namrata Karnam - C# Intermediate - Delegates in C# (Func, Action)
Marinko Spasojevic - How to stress and measure the Garbage Collector
CalvinH - Embedding quotes within a C# string - The Wit and Ramblings of David Giard
David Giard - Side by Side user scoped .NET Core installations on Linux with dotnet-install.sh
Scott Hanselman - Subqueries in LINQ -- Visual Studio Magazine
Peter Vogel
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cancelación de peticiones en ASP.NET Core y MVC
José María Aguilar - Cómo reconocer a los buenos desarrolladores
José María Aguilar
.NET / .NET Core
- Dependabot for .NET Core dependency tracking in GitHub
Scott Hanselman - Use structures to improve the lisibility of your code
Gérald Barré - Venciendo el miedo a las pruebas unitarias en .Net
Jorge Turrado - C# Intermetiade - Queue, Stack and Hashtable Collections in C#
Marinko Spasojevic - .NET Core Source Code Analysis with Intel® VTune™ Amplifier
Varun Venkatesan, Li Tian & Denis Pravdin - Comparing speed of ToUpper, ToUpperInvariant, ToLower and ToLowerInvariant in .NET Framework and .NET Core
Jiří Činčura - Secure Random Integers in .NET Core 3
Kevin Jones - Playing with C# 7
Adam Storr - Performance in .NET – Part 2
Ricardo Peres
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.
Por si te lo perdiste...
- ¿Dónde está Server.MapPath() en ASP.NET Core?
José M. Aguilar - 7 Hábitos de personas altamente innovadoras
José M. Aguilar
.NET / .NET Core
- Announcing .NET Core 2.2 Preview 3
Rich Lander - No InternalsVisibleTo, no problem – bypassing C# visibility rules with Roslyn
Filip Woj - Announcing ML.NET 0.6 (Machine Learning .NET)
César de la Torre - Working with the Dynamic Type in C#
Camilo Reyes - Using multiple instances of strongly-typed settings with named options in .NET Core 2.x
Andrew Lock - New prescriptive guidance for Open Source .NET Library Authors
Scott Hanselman - Nice little trick when working with Expression API
Sacha Barber - .Net Core 2: Managing Secrets in Web Apps - TechNet Articles - United States (English)
Jayendran arumugam - When Is It Okay to Use a C# Partial Class?
Carlos Schults - C# Intermediate - Abstract Classes in C#
Marinko Spasojevic - Don't Code Tired | Setting Up Mock ref Return Values in Moq
Jason Roberts - #MLNET – Analizando datos de la Pipeline con la nueva version API 0.6.0 (gracias LINQ!)
Bruno Capuano - Inyección de Dependencias en .Net Framework
Jorge Turrado
Por si te lo perdiste...
- ¿Recomendarías a tu hijo que se dedicase al mundo del desarrollo de software?
José M. Aguilar - Cómo incluir scripts en la página desde vistas parciales ASP.NET Core MVC con DynamicSections
José María Aguilar
.NET / .NET Core
- .NET Core 2.0 Sees End of Life, 2.1.5 Update Released
David Ramel - Update on .NET Core 3.0 and .NET Framework 4.8
Scott Hunter - I didn't understand why people struggled with (.NET's) async
Dan - C# Intermediate: Structures in C# & Enumerations in C#
Marinko Spasojevic - The danger of TaskCompletionSource<T> class
Sergey Teplyakov - Using Async with ManualResetEventSlim
Calvin H. - BenchmarkMockNet: Benchmarking .NET Mocking Libraries
Steve Desmond - Middle Ground between Server and Workstation GC
Maoni Stephens - Unit Testing With .NET Core
Jeremy Morgan - .NET Tip: Testing Private Fields
Peter Vogel - A Recap about Creating Maps for AutoMapper in .NET Core
Silvia Campo - FixedTimeEquals in .NET Core
Kevin Jones - LINQ Stinks - code smells in your LINQ
Mark Heath - A History of .NET Runtimes
Matt Warren


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