Skip to content

v5.20 Release

Compare
Choose a tag to compare
@github-actions github-actions released this 28 Nov 05:50
· 228 commits to main since this release

✨ Looking For Sponsors ✨

FastEndpoints needs sponsorship to sustain the project. Please help out if you can.


New 🎉

Support for .Net 8.0

The project is now developed and built using .NET 8.0 while supporting .NET 6 & 7 as well. You can upgrade your existing projects simply by targeting .NET 8

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
     </PropertyGroup>
</Project>

The .NET 8 Request Delegate Generator is not yet compatible with FastEndpoints as FE has it's own endpoint mapping and model binding system which will require a complete rewrite as a Source Generator to properly support Native AOT. We're currently investigating ways to achieve that but cannot give a timeframe on completion as it's a massive undertaking. You can see our internal discussion about this matter on discord.

Simpler way to register Pre/Post Processors with DI support

Processors can now be configured just by specifying the type of the processor without the need for instantiating them yourself.

public class MyEndpoint : EndpointWithoutRequest
{
    public override void Configure()
    {
        ...
        PreProcessor<PreProcessorOne>();
        PreProcessor<PreProcessorTwo>();
    }
}

While the old PreProcessors(...) method continues to work, the new method automatically resolves any constructor injected dependencies without you having to manually register the processors in DI.

Exception handling capability for Post-Processors

Post-Processors can now handle uncaught exceptions as an alternative to an exception handling middleware.
Please see the documentation page for details.

Shared state support for global Pre/Post Processors

Global Pre/Post Processors now have shared state support with the following two newly added abstract types:

  • GlobalPreProcessor<TState>
  • GlobalPostProcessor<TState>
Ability to hide the error reason in the JSON response when using the default exception handler middleware

The actual error reason can now be hidden from the client by configuring the exception handler middleware like so:

app.UseDefaultExceptionHandler(useGenericReason: true);

Fixes 🪲

Auto binding collections of form files fails after first request

An object disposed error was being thrown in subsequent requests for file collection submissions due to a flaw in the model binding logic, which has now been corrected.

Incorrect validation error field names when nested request DTO property has [FromBody] attribute

JSON error responses didn't correctly render the deeply nested property chain/paths when the following conditions were met:

  • Request DTO has a property annotated with [FromBody] attribute
  • The bound property is a complex object graph
  • Some validation errors occur for deeply nested items

This has been fixed to correctly render the property chain of the actual item that caused the validation failure.

More info here.

Test assertions couldn't be done on ProblemDetails DTO

The ProblemDetails DTO properties had private setter properties preventing STJ from being able to deserialize the JSON which has now been corrected.

Minor Breaking Changes ⚠️

Pre/Post Processor interface changes

Due to the Processor related new features introduced in this release, the *ProcessAsync(...) method signatures had to be changed. The previous arguments are still available but they have been grouped/pushed into a processor context object. The new method signatures look like the following. Migrating your existing pre/post processors shouldn't take more than a few minutes.

PreProcessor Signature:

sealed class MyProcessor : IPreProcessor<MyRequest>
{
    public Task PreProcessAsync(IPreProcessorContext<MyRequest> ctx, CancellationToken c)
    {
        ...
    }
}

PostProcessor Signature:

sealed class MyProcessor : IPostProcessor<MyRequest, MyResponse>
{
    public Task PostProcessAsync(IPostProcessorContext<MyRequest, MyResponse> ctx, CancellationToken c)
    {
        ...
    }
}
AddJWTBearerAuth() default claim type mapping behavior change

The JwtSecurityTokenHandler.DefaultInboundClaimTypeMap static dictionary is presently used by ASP.NET for mapping claim types for inbound claim type mapping. In most cases people use JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear() to not have long claim types such as http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier as the claim type for the sub claim for example.

The default behavior has now been changed to make the claim types not use the SOAP type identifiers like above. If for some reason you'd like to revert to the old behavior, it can be achieved like so:

.AddJWTBearerAuth("jwt_signing_key", o =>
{
    o.MapInboundClaims = true;
});

If using the new default behavior, it is highly recommended to invalidate any previously issued JWTs by resetting your JWT signing keys or any other means neccessary to avoid any potential issues with claim types not matching. This obviously means your clients/users will have re-login (obtain new JWTs). If that's not an option, simply set .MapInboundClaims = true; as mentioned above to use the previous behavior.

See #526 for more info.