Press "Enter" to skip to content

The best new features in ASP.NET Core 7

An important part of Microsoft’s “cloud-first” .NET 7 release in November, ASP.NET Core 7 brings powerful new tools to the web development framework to help developers build modern web applications. Built on top of the .NET Core runtime, ASP.NET Core 7 has everything you need to build cutting-edge web user interfaces and robust back-end services on Windows, Linux, and macOS alike.

This article discusses the highlights of ASP.NET Core 7 and includes some code samples to get you started with the new features. To work with the code samples provided in this article, you must have Visual Studio 2022 installed on your computer. If you don’t have a copy, you can download Visual Studio 2022 here.

Now let’s dive into the best new features in ASP.NET Core 7.

Output caching middleware

ASP.NET Core 7 enables you to use output caching in all ASP.NET Core applications: Minimal API, MVC, Razor Pages, and Web API applications with controllers. To add the output caching middleware to the service collection, call the IServiceCollection.AddOutputCache extension method. To add the middleware to the request processing pipeline, call the IApplicationBuilder.UseOutputCache extension method.

Then, to add a caching layer to an endpoint, you can use the following code.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("https://www.infoworld.com/", () => "Hello World!").CacheOutput();
app.Run();

Rate Limiting Middleware

Controlling the rate at which clients can make requests to endpoints is an important security measure that allows web applications to prevent malicious attacks. You can prevent denial of service attacks, for example, by limiting the number of requests coming from a single IP address in a given period of time. The term for this capability is rate limiting.

The Microsoft.AspNetCore.RateLimiting middleware in ASP.NET Core 7 can help you enforce rate limiting in your application. You can configure rate limiting policies and then attach those policies to endpoints, thus protecting those endpoints from denial of service attacks. This middleware is particularly useful for public web applications that are susceptible to this type of attack.

You can use the rate limiting middleware with ASP.NET Core Web API, ASP.NET Core MVC, and ASP.NET Core Minimal API applications. To start using this built-in middleware, add the Microsoft.AspNetCore.RateLimiting NuGet package to your project by running the following command at the Visual Studio command prompt.

dotnet add package Microsoft.AspNetCore.RateLimiting

Alternatively, you can add this package to your project by running the following command in the NuGet package manager console or console window:

Install-Package Microsoft.AspNetCore.RateLimiting

Once the rate-limiting middleware has been installed, include the code snippet below in your Program.cs file to add rate-limiting services with default settings.

builder.Services.AddRateLimiter(options =>
{
});

Request decompression middleware

ASP.NET Core 7 includes a new request decompression middleware that enables endpoints to accept requests with compressed content. This eliminates the need to explicitly write code to decompress requests with compressed content. It works by using a content-encoding HTTP header to identify and decompress compressed content in HTTP requests.

In response to an HTTP request that matches the content-encoding header value, the middleware encapsulates HttpRequest.Body in an appropriate decompression stream using the matching provider. This is followed by removal of the content-encoding header, indicating that the request body is no longer compressed. Note that the request decompression middleware ignores requests without a content-encoding header.

The following code snippet shows how you can enable request decompression for the default content encoding types.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRequestDecompression();
var app = builder.Build();
app.UseRequestDecompression();
app.MapPost("https://www.infoworld.com/", (HttpRequest httpRequest) => Results.Stream(httpRequest.Body));
app.Run();

The default decompression providers are Brotli, Deflate, and Gzip compression formats. Their content-encoding header values ​​are br, deflate, and gzip, respectively.

Filters on minimal APIs

Filters allow you to run code during certain stages in the request processing pipeline. A filter is executed before or after the execution of an action method. You can take advantage of filters to track web page visits or validate request parameters. By using filters, you can focus on the business logic of your application instead of writing code for the cross-cutting issues of your application.

An endpoint filter allows you to intercept, modify, short-circuit, and add cross-cutting issues such as authorization, validation, and exception handling. The new IEndpointFilter interface in ASP.NET Core 7 allows us to design filters and connect them to API endpoints. These filters can change the request or response objects or cause a short circuit in the request processing. An endpoint filter can be called on actions and route endpoints.

The IEndpointFilter interface is defined in the Microsoft.AspNetCore.Http namespace as shown below.

public interface IEndpointFilter
{
    ValueTask<object?> InvokeAsync(
        EndpointFilterInvocationContext context,
        EndpointFilterDelegate next);
}

The following code snippet illustrates how multiple endpoint filters can be chained together.

app.MapGet("https://www.infoworld.com/", () =>
{
    return "Demonstrating multiple endpoint filters.";
})
.AddEndpointFilter(async (endpointFilterInvocationContext, next) =>
    {
        app.Logger.LogInformation("This is the 1st filter.");
        var result = await next(endpointFilterInvocationContext);
        return result;
    })
.AddEndpointFilter(async (endpointFilterInvocationContext, next) =>
    {
        app.Logger.LogInformation("This is the 2nd filter.");
        var result = await next(endpointFilterInvocationContext);
        return result;
    })
.AddEndpointFilter(async (endpointFilterInvocationContext, next) =>
    {
        app.Logger.LogInformation("This is the 3rd Filter.");
        var result = await next(endpointFilterInvocationContext);
        return result;
    });

Parameter binding in action methods using DI

With ASP.NET Core 7, you can take advantage of dependency injection to bind parameters in the action methods of your API controllers. So if the type is configured as a service, you no longer need to add the [FromServices] attribute to the parameters of your method. The following code snippet illustrates this.

[Route("[controller]")]
[ApiController]
public class MyDemoController : ControllerBase
{
    public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
}

Results written to minimal APIs

The IResult interface was added in .NET 6 to represent return values ​​from minimal APIs that do not use implicit JSON support that serializes the returned object. It should be noted here that the static Result class is used to create various IResult objects that represent different types of responses, such as setting a return status code or redirecting the user to a new URL. However, because the frame types returned by these methods were private, it was not possible to verify the correct IResult type returned by the action methods during unit tests.

Also Read:  GitHub owns up to service issues, multiple outages

With .NET 7, framework types that implement the IResult interface are now public. Therefore, we can use type assertions when writing our unit tests, as shown in the code snippet below.

[TestClass()]
public class MyDemoApiTests
{
    [TestMethod()]
    public void MapMyDemoApiTest()
    {
        var result = _MyDemoApi.GetAllData();
        Assert.IsInstanceOfType(result, typeof(Ok<MyDemoModel[]>));
    }     
}

You can also use IResult implementation types to unit test your route controllers on minimal APIs. The following code snippet illustrates this.

var result = (Ok<MyModel>)await _MyDemoApi.GetAllData()

Route groups in minimal APIs

With ASP.NET Core 7, you can take advantage of the new MapGroup extension method to organize groups of endpoints that share a common prefix across their minimal APIs. The MapGroup extension method not only reduces boilerplate code, but also makes it easy to customize entire groups of endpoints.

The following code snippet shows how MapGroup can be used.

app.MapGroup("/public/authors")
    .MapAuthorsApi()
    .WithTags("Public");

The following code snippet illustrates the MapAuthorsApi extension method.

public static class MyRouteBuilder
{ 
public static RouteGroupBuilder MapAuthorsApi(this RouteGroupBuilder group)
    {
        group.MapGet("https://www.infoworld.com/", GetAllAuthors);
        group.MapGet("/{id}", GetAuthor);
        group.MapPost("https://www.infoworld.com/", CreateAuthor);
        group.MapPut("/{id}", UpdateAuthor);
        group.MapDelete("/{id}", DeleteAuthor);
        return group;
    }
}

Health checks for gRPC

ASP.NET Core supports the use of the .NET Health Checks middleware to report on the health of your application’s infrastructure components. ASP.NET Core 7 adds built-in support for monitoring the health of gRPC services using the Grpc.AspNetCore.HealthChecks NuGet package. You can use this package to expose an endpoint in your gRPC application that enables health checks.

Note that you would typically use health checks with an external monitoring system or with a load balancer or container orchestrator. The latter could automate an action like restarting or redirecting the service based on health status. You can read more about ASP.NET Core health checks here.

Minimal API file uploads

You can now use IFormFile and IFormFileCollection in minimal APIs to upload files in ASP.NET Core 7. The following code snippet illustrates how IFormFile can be used.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost("/uploadfile", async (IFormFile iformFile) =>
{
    var tempFileName = Path.GetTempFileName();
    using var fileStream = File.OpenWrite(tempFileName);
    await iformFile.CopyToAsync(fileStream);
});
app.Run();

If you want to upload multiple files, you can use the following code instead.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost("/uploadfiles", async (IFormFileCollection files) =>
{
    foreach (var file in files)
    {
        var tempFileName = Path.GetTempFileName();
        using var fileStream = File.OpenWrite(tempFileName);
        await file.CopyToAsync(fileStream);
    }
});
app.Run();

From output caching, rate limiting, and request decompression middleware to filters, route maps, and other new capabilities for minimal APIs, ASP.NET Core 7 provides developers with many new features that will make it much easier and more quickly build robust web applications. ASP.NET Core 7 enables faster development with modular components, offers better performance and scalability across multiple platforms, and simplifies deployment to web servers, Docker, Azure, and other hosting environments with built-in tools.

In this article, we take a look at just a few of the important new features in ASP.NET Core 7 – my top picks. You can find the full list of new features in ASP.NET Core 7 here.

Copyright © 2023 IDG Communications, Inc.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *