Daily Knowledge Drop
To create custom ASP.NET Core middleware
, all that is required is a class with an Invoke or InvokeAsync method
. However, if configured incorrectly, the error will not be apparent until runtime.
The IMiddleware
interface can be used to ensure custom middleware contains the correct method, through the implementation of the interface, ensuring any configuration errors are apparent at compile time.
Weakly typed
To define a working middleware component, a class with an Invoke
or InvokeAsync
method needs to be defined:
public class WeakTypeMiddleware
{
private readonly RequestDelegate _next;
public WeakTypeMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
Console.WriteLine($"Hello from {nameof(WeakTypeMiddleware)}");
await _next.Invoke(httpContext);
}
}
And the components must be added to the middleware pipeline:
app.UseMiddleware<WeakTypeMiddleware>();
However, nothing is preventing the middleware component from accidentally being configured incorrectly
- in the below example the class doesn't contain a method with the correct name:
public class WeakTypeMiddleware
{
private readonly RequestDelegate _next;
public WeakTypeMiddleware(RequestDelegate next)
{
_next = next;
}
// incorrect method name used
public async Task InvokePipeline(HttpContext httpContext)
{
Console.WriteLine($"Hello from {nameof(WeakTypeMiddleware)}");
await _next.Invoke(httpContext);
}
}
The above class is a valid class, but not a valid middleware component. The above code will compile, but an exception will occur when trying to call an endpoint which makes use of the component:
System.InvalidOperationException: 'No public 'Invoke' or 'InvokeAsync'
method found for middleware of type 'WeakTypeMiddleware'.'
The exception tells us exactly what the problem is, and how to resolve it - it is easily fixed. However a better and cleaner approach is to never encounter the exception in the first place.
Strongly typed
A middleware component can be strongly typed by using the IMiddleware
interface:
public class StrongTypeMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
Console.WriteLine($"Hello from {nameof(StrongTypeMiddleware)}");
await next.Invoke(context);
}
}
The interface enforces the InvokeAsync
method on the implementation, ensuring it will be configured correctly.
A slight difference between the two,is that with the weakly typed implementation, the next delegate is passed into the constructor
, however with the strongly typed implementation, the next delegate is passed into the InvokeAsync method
.
Notes
Implementing strongly typed middleware using IMiddleware
instead of having the components weakly typed is a minor code change, and may not offer any immediately obvious benefits - however, using the interface will ensure code uniformity across all middleware components, as well as make it easier to find and identify middleware components in a large code base.
References
Strongly Typed Middleware in ASP.NET Core
Daily Drop 170: 28-09-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.On This Page