Every year, a new version of dotnet, my preferred framework, is launched. I went through each preview version before the final release and, in no particular order, chose the 5 New ASP.NET Core Features in dotnet 8 You’ll Love this Year. Microsoft has already developed many preview versions of the upcoming version, which will be accessible in a few months. The goal of Microsoft engineers is to make ASPnet core the best web framework ever. They actively listen to us (the community) and work tirelessly to improve the framework.
I’ve been keeping track of every ASPnet core update preview release for dotnet 8, and as of the time I was writing this article, we were on preview 6. I’m excited about the new capabilities, and in this blog I’ll share my five picks for the future ASPnet core upgrades in DotNet 8.
Global Exception Handling
If you’re an experienced ASP.NET Core developer, you’ve probably already put in place measures to capture every exception, report them, respond to clients appropriately, and make sure no important data is exposed in production. To automate this procedure, numerous blog entries and nugget packages have been made available over time. Now, with DotNet 8, we can easily integrate it to ASPnet Core.
This is possible thanks to the “IExceptionHandler” type that was added in dotnet 8. ASPnet core already had an Exception handler middleware that was added in previous dotnet versions. But this interface makes it possible to inject some custom exception-handling logic behind the scenes.
You first need to implement this interface, for your exception-handling logic, you can implement as many as you can, and they will be executed by order of registration.
Then, register it as follow. Where “T” is the type of your Exception handler class.
IServiceCollection.AddExceptionHandler<T>
Support for native AOT in ASP.net core
First, what is AOT and JIT? () and (Just in time compilation)
AOT: Ahead of Time Compilation
This is when source code written in a high-level programming language is compiled into a lower-level programming language before execution.
JIT: Just in Time Compilation
This is the process of compiling a program while it is running. This has always been used in dotnet to translate any dotnet language into machine code when necessary. When the dotnet language code (C#, F#, etc.) is executed, the JIT compiler converts the CIL language used to create the “.exe” or “dll” into the native OS code.
We now have the option to create and publish console programs as native AOT thanks to Dotnet 7, which was released last year. We will now be able to compile and publish ASP.net core programs as native AOT in dotnet 8.
What does this change?
After understanding JIT and comparing it to AOT, you’ll quickly see the difference. The software you write could be deployed as a platform-specific, package that is smaller in size, consumes less memory, and quicker to launch, without the dotnet runtime installed on the device.
Add Authorization Policies Easily
A lot of code is written while implementing authorisation policies. especially if you want to give your policies their own unique qualities. With fewer lines of code and a new feature in dotnet 8, Asp.net core can now easily build permission policies. IAuthorizationRequirementData’s addition makes this possible. The benefit of this is that the attribute definition can now also include the conditions related to the authorisation policy.
I’ll give you an example right away because that will best show you how this is an improvement. You’ll quickly see why this is great if you contrast it with the previous method of creating authorization policies. This demonstration is taken from a Microsoft resource.
[ApiController]
[Route(“api/[controller]”)]
public class GreetingsController : Controller
{
[MinimumAgeAuthorize(16)]
[HttpGet(“hello”)]
public string Hello() => $”Hello {(HttpContext.User.Identity?.Name ?? “world”)}!”;
}
class MinimumAgeAuthorizeAttribute : AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationRequirementData
{
public MinimumAgeAuthorizeAttribute(int age) => Age =age;
public int Age { get; }
public IEnumerable<IAuthorizationRequirement> GetRequirements()
{
yield return this;
}
}
class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;
public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
{
_logger = logger;
}
// Check whether a given MinimumAgeRequirement is satisfied or not for a particular context
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeAuthorizeAttribute requirement)
{
// Log as a warning so that it’s very clear in sample output which authorization policies
// (and requirements/handlers) are in use
_logger.LogWarning(“Evaluating authorization requirement for age >= {age}”, requirement.Age);
// Check the user’s age
var dateOfBirthClaim = context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth);
if (dateOfBirthClaim != null)
{
// If the user has a date of birth claim, check their age
var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value, CultureInfo.InvariantCulture);
var age = DateTime.Now.Year – dateOfBirth.Year;
if (dateOfBirth > DateTime.Now.AddYears(-age))
{
// Adjust age if the user hasn’t had a birthday yet this year
age–;
}
// If the user meets the age criterion, mark the authorization requirement succeeded
if (age >= requirement.Age)
{
_logger.LogInformation(“Minimum age authorization requirement {age} satisfied”, requirement.Age);
context.Succeed(requirement);
}
else
{
_logger.LogInformation(“Current user’s DateOfBirth claim ({dateOfBirth}) does not satisfy the minimum age authorization requirement {age}”,
dateOfBirthClaim.Value,
requirement.Age);
}
}
else
{
_logger.LogInformation(“No DateOfBirth claim present”);
}
return Task.CompletedTask;
}
New ASP.net core metrics
In the past, implementing telemetry and diagnostic features in your software required you to write code tidily coupled with the telemetry provider’s SDK. Once you needed to switch to a new vendor, you’d often need to re-write the instrumentation code. This was a problem and needed to be addressed.
To address this, System.Diagnostics.Metrics API was created. This provides cross-platform APIs for telemetry and was designed in collaboration with Open Telemetry. Open telemetry adoption makes telemetry more flexible. Why? you may ask. To answer your question, I’ll quote this from Microsoft’s docs.
But what does it have to do with ASP.net Core?
Now you understand the necessity of having an industry-wide standard for collecting metrics. This has been added to parts of ASP.net core. Including Kestrel, Hosting, and Signal-R. Microsoft has put at our disposal a sample source code, with a Grafana dashboard that reports metrics collected from the ASP.net core app by Prometheus.
What is Prometheus?
To answer this question, I’ll simply quote what is on their website. Since it is very clear. Here is a link to their website.
Better Debugging Experience
Playing the detective with your source code is now more fun. Finding important and precise information on types like the HttpContext and WebApplication is a lot easier on dotnet 8. Even IConfiguration values are easily displayed on the debug window. This improvement is depicted here.
Conclusion
As I said earlier, the dotnet team is treating its developers as first-class customers, and I love that! I can’t wait to see the latest dotnet 8 release and upgrade my projects in accordance with the improvements and new features coming. There are more features added that I love, like better authentication for example, but I just decided to pick 5 of them. What’s the feature you love most?