Version 7.0 of the .NET platform brought many new features in this article I will focus on the main resources that were added to the platform to leverage Web development such as middleware, and minimal APIs, among others.
1 – Middleware output caching
ASP.NET Core 7 lets you use output caching in all ASP.NET Core apps: Minimal API, MVC, Razor Pages, and web API apps with controllers.
The “Output Caching Middleware” feature that can be used to implement output caching in a web application and Output Caching Middleware allows you to cache the output generated by an HTTP request and serve it directly from the cache to subsequent requests, thus improving application performance.
To add output caching middleware to the service collection, invoke the IServiceCollection.AddOutputCache extension method, and 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.
It is important to highlight that:
-> In applications using CORS middleware, UseOutputCache must be called after UseCors.
-> In Razor Pages apps and apps with controllers, UseOutputCache must be called after UseRouting.
-> Calling AddOutputCache and UseOutputCache does not initiate the caching behavior but makes the cache available.
2 – 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 by limiting the request number from a single IP address in a given period.
The Microsoft.AspNetCore.RateLimiting middleware in ASP.NET Core 7 can help you enforce rate limiting on your application. You can configure rate-limiting policies and then attach those policies to endpoints, thereby protecting those endpoints from denial-of-service attacks. This middleware is particularly useful for public-facing web applications that are susceptible to these attacks.
You can use rate-limiting middleware with ASP.NET Core Web API, ASP.NET Core MVC, and ASP.NET Core Minimal API apps. To get started using this built-in middleware, add 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
You can also use the following command in the Package Manager Console window:
After installing Rate Limiting Middleware, add the code snippet below to your Program.cs file to add rate-limiting services with the default configuration:
In the following example, using the fixed window of time and number of requests and the variable window of time and request number:
Several strategies can be used to implement rate limiting in ASP.NET Core. Some common approaches include:
IP-based limit: Restricts the number of requests allowed per IP address in a given period. This is useful for limiting requests from a single client or a specific IP address.
API key-based limiting: If an application uses API key authentication, rate limiting can be applied to each key individually. This allows you to control the request rate for each client or application using the key.
Limit based on user ID: If the application requires user authentication, rate limiting can be based on user ID. This allows each user to have a specific request rate.
For details see the following video: ASP.NET Core – Using Rate Limiting
3 – Request Unpacking Middleware
ASP.NET Core 7 includes new Request Decompression Middleware that allows endpoints to accept requests with compressed content. This eliminates the need to explicitly write code to unzip requests with zipped content.
Request compression is useful when you want to reduce the size of data transferred between the client and the server, especially in scenarios where bandwidth is limited or when you have large volumes of data being transmitted. Compression can help improve application performance, reduce latency, and decrease bandwidth consumption.
This feature works 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 the HttpRequest.Body into a suitable uncompressed stream using the corresponding provider.
This is followed by the removal of the Content-Encoding header, which indicates that the request body is no longer compressed. Note that the decompression middleware ignores requests without a Content-Encoding header. Below is a code snippet that shows how you can enable request decompression for the default content encoding types:
The default decompression providers are Brotli, Deflate, and Gzip compression formats. Its content-encoding header values are br, deflate, and gzip, respectively.
4 – Filters in minimal APIs
Filters allow you to run code during certain stages in the request processing pipeline. A filter runs before or after an action method executes, and you can leverage filters to track visits to the web page or validate request parameters.
By using filters, you can focus on your application’s business logic instead of writing code for your application’s cross-cutting concerns.
An endpoint filter lets you intercept, modify, short-circuit, and aggregate cross-cutting issues like authorization, validation, and exception handling, and the new IEndpointFiltern interface in ASP.NET Core 7 lets us design filters and hook them up to API endpoints.
These filters can change the request or response objects or interrupt request processing. An endpoint filter can be invoked on actions and route endpoints.
The IEndpointFilter interface is defined in Microsoft.AspNetCore.Http namespace as shown below:
Here is an example of how to create an endpoint filter using this interface:
In the example above, the CustomEndpointFilter class implements the IEndpointFilter interface and defines two asynchronous functions: OnExecutingAsync and OnExecutedAsync. The OnExecutingAsync function is called before the endpoint executes, allowing you to add custom logic such as authentication or request validation.
The OnExecutedAsync function is called after the endpoint executes, allowing you to add post-processing logic.
The following is a code snippet illustrating how multiple endpoint filters can be chained together:
Using the new IEndpointFilter interface, you can add custom logic at specific points in the endpoint processing pipeline, providing a more flexible way to control the flow of execution and add custom functionality to your minimal APIs in ASP.NET Core 7.0.
See also my article: NET 7 – Using Filters in Mininal APIs
5- Association of parameters in Action methods using DI
With ASP.NET Core 7, you can leverage dependency injection to bind parameters in the Action methods of your API controllers. Therefore, if the type is configured as a service, it is no longer necessary to add the [FromServices] attribute to your method’s parameters.
Before ASP.NET Core 7.0, it was necessary to use [FromServices] or [FromBody] annotations on action parameters to signal the framework how they should be bound. With parameter binding feature introduction using DI, you no longer need these annotations explicitly.
Now you can declare a parameter in a controller action method, and ASP.NET Core will use the DI engine to automatically resolve and bind that parameter based on your DI configuration.
Here is an example using this feature:
In the example above, the action method MinhaAction has three parameters: id, nome, and meuModel. These parameters will be automatically resolved and bound using ASP.NET Core 7.0’s DI engine, with no additional annotations required.
ASP.NET Core will look for registered implementations for the parameter types in the DI container and automatically provide them to the action method.
This feature can simplify the code of Action methods, removing the need for additional annotations and improving the development experience.
6- Typed results in minimal APIs
The “Typed Results” feature in ASP.NET Core 7.0’s Minimal APIs refers to functionality that makes it easier to return typed results in API Action methods. With this feature, you can return strongly typed action results without the need to use the ActionResult<T>, OkObjectResult, NotFoundObjectResult, and other classes.
The idea behind “Typed Results” is to provide a simpler and more intuitive way to return action results with a specific type, allowing you to focus on the actual result instead of worrying about creating an ActionResult or ObjectResult object.
The IResult interface was added in .NET 6 to represent values returned from minimal APIs that do not use implicit support for JSON serialization of the returned object. It should be noted here that the static Result class is used to create several 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 framework types returned from these methods were private, it was not possible to verify the correct type of IResult being returned from Action methods during unit testing.
With .NET 7, framework types implementing the IResult interface are now public. So we can use type assertions when writing our unit tests, as shown in the code snippet below.
Below is another example of “Typed Results” usage:
In the example above, an Action method is mapped to the “/api/minhaaction” route using the MapGet method.
Instead of explicitly returning an ActionResult or ObjectResult object, it is possible to directly return an instance of type MeuModel since ASP.NET Core 7.0 can infer the result type and automatically convert it into an appropriate HTTP response.
With the use of “Typed Results”, the code becomes simpler and more readable, eliminating the need to explicitly create ActionResult or ObjectResult objects.
This functionality is useful when developing APIs with Minimal APIs, which aim to provide a more concise and streamlined development experience.
7- Routing groups in minimal APIs
With ASP.NET Core 7, you can leverage the new MapGroup extension method to organize groups of endpoints that share a common prefix into your minimal APIs. The MapGroup extension method reduces repetitive code and makes it easy to customize entire groups of endpoints.
Before ASP.NET Core 7.0, in minimalist APIs, all routes were defined directly in the scope of the WebApplication object. This could lead to cluttered and difficult-to-read code when there are multiple routes.
With the “Route Groups” feature, you can group related routes into logical blocks using the Map method on an IEndpointRouteBuilder object. This helps improve code organization, making it more readable and maintainable.
The following code snippet illustrates how the MapGroup can be used:
The next code snippet illustrates the MapAutorsApi extension method usage:
Here is another example using the “Route Groups” feature:
In the example above, routes related to users and products are grouped inside the /api block using the Map method. Within each block, you can define the specific routes related to that group.
By grouping related routes, you improve code readability and ease of maintenance. In addition, it is possible to apply authentication and authorization filters or policies to an entire group of routes instead of defining them individually for each one.
The “Route Groups” feature is a valuable addition to ASP.NET Core 7.0’s Minimal APIs, allowing you to organize and structure code more clearly and concisely, making API development and maintenance more efficient.
8 – File uploads in minimal APIs
In previous ASP.NET Core versions, file upload support required additional configuration and manual manipulation of file data.
With ASP.NET Core 7.0, file upload support is streamlined in Minimal APIs, allowing you to easily handle to receive files sent via an HTTP request.
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.
If you want to upload multiple files, you can use the following code snippet:
ASP.NET Core 7.0 automatically handles the incoming file in the HTTP request and converts it to an IFormFile object so you can easily manipulate it in action method code.
With this feature, the file upload process in minimalist APIs is simplified, allowing you to focus on the file processing logic without the need to manually handle extracting and manipulating file data.
For more details, see my article: NET 7 – Mininal APIs: File Upload
9- Health checks for gRPC
ASP.NET Core supports using the Health Checks middleware to report the health of your application’s infrastructure components.
Integrity checks are an essential part of monitoring and operating distributed systems. They allow you to verify that your services are working correctly and available to handle requests.
ASP.NET Core 7 now adds built-in support for monitoring the health of gRPC services via the Grpc.AspNetCore.HealthChecks nuget package. You can use this package to expose an endpoint in your gRPC application that allows 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 can automate an action such as restarting or redirecting the service based on health status.
With this new feature, you can define specific health checks for your gRPC services and expose a dedicated endpoint to check the health status of the service.
Here is an example of how to use the feature:
In the example above, we are adding support for health checks for gRPC services using AddGrpcHealthChecks and then mapping a “/health” endpoint to the gRPC service health checks using MapGrpcHealthChecks. Additionally, we are mapping a gRPC service called MyGrpcService using MapGrpcService.
These lines of code allow you to expose a “/health” endpoint that can be used to check the health status of the gRPC service. You can customize health checks to your gRPC service needs by adding custom logic to check components, database connections, external services, etc.
With this feature, you can have more comprehensive control over the health of your gRPC services and ensure they are up and running and ready to handle customer requests. This contributes to the reliability and stability of your distributed system.
Thus, we have nine important features that were added to ASP.NET Core in version 7.0 that will improve web development in several aspects.
*The content of this article is the author’s responsibility and does not necessarily reflect the opinion of iMasters.