⚠ Deprecated: Legacy
Middleware and Attributes to simplify Minimal API Development
$ dotnet add package AspNetCore.MinimalApi.ExtA set of tools to simplify creating AspNetCore applications, specifically when using MinimalAPIs.
The middleware helps clean up your code by making it easy to break the application startup into seperate classes, ideally named by what their purpose is.
This project is forked and a lot of changes has been made. Click to go original repository
AspNetCore applications, with at least .NET 7.0
Install the package from NuGet:
Install-Package AspNetCore.MinimalApi.Ext
Install the package from CLI:
dotnet add package AspNetCore.MinimalApi.Ext
This project still under development and there might be breaking changes or bugs, be careful when you use it.
By utilizing these attributes, you can quickly and easily get endpoints created from any file that uses them. By default the names of the containing folder path and class name will be the names of the endpoints, requiring as little code/effort as possible.
This is a fully functional file that will create a fully functional endpoint for /Sample
using AspNetCore.MinimalApi.Ext;
namespace WebApplication1.Endpoints;
[Endpoint]
public class Sample
{
public string Handle(HttpContext context)
{
return "Hello World!";
}
}
using AspNetCore.MinimalApi.Ext;
namespace WebApplication1.Endpoints;
[Endpoint(HttpMethodType.Post)] // Url will be PREFIX/SamplePost
public class SamplePost
{
public string Handle(HttpContext context)
{
return "Hello World!";
}
}
using AspNetCore.MinimalApi.Ext;
namespace WebApplication1.Endpoints;
[Endpoint(HttpMethodType.Post, CustomRoute = "Sample/Post")] // Url will be PREFIX/Sample/Post
public class SamplePost
{
public string Handle(HttpContext context)
{
return "Hello World!";
}
}
using AspNetCore.MinimalApi.Ext;
namespace WebApplication1.Endpoints;
[Endpoint(HttpMethodType.Post, ActionName = "Sample_Post")] // Url will be PREFIX/Sample_Post
public class SamplePost
{
public string Handle(HttpContext context)
{
return "Hello World!";
}
}
Every class that has Endpoint attribute will automatically be processed for creating endpoints. Only one "Handle" method will be considered as an endpoint. You can change the name of the method by overriding EndpointOptions.
Library does not support multiple endpoints per class. You can create multiple classes in a single file but not 2 or more endpoints in a single class.
By using this on attribute;
If you do not pass any parameters, HttpMethod will be GET and route will be generated automatically.
By using this on attribute, you can use custom filters that assigned from IEndpointFilter interface.
CustomFilter.cs
/// <summary>
/// This is an example of a custom filter that can be used to authorize/validate a request.
/// </summary>
public class CustomFilter : IEndpointFilter
{
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
{
var idFromQuery = context.HttpContext.Request.Query["id"].FirstOrDefault();
if (idFromQuery != "1234") context.HttpContext.Response.StatusCode = 401;
return await next(context);
}
}
EndpointFile.cs
using AspNetCore.MinimalApi.Ext;
namespace WebApplication1.Endpoints;
[Endpoint(HttpMethodType.Post, ActionName = "Sample_Endpoint_With_Filter")] // Url will be PREFIX/Sample_Post
[EndpointFilter(typeof(CustomFilter))]
public class SampleFilterEndpoint
{
public string Handle(HttpContext context)
{
return "Hello World!";
}
}
Currently here are the supported attributes;
Custom attributes provided by the library currently only way to set Method and route and can only be used on the classes.
You can use EndpointOptions to configure the middleware.
This will add EndpointOptions as singleton to the services.
builder.Services.AddMinimalApiEndpointOptions(x => {
x.GlobalPrefix = "api/v1"; //Url: /api/Product/Get etc.
//Global filters
x.EndpointFilters = new List<Type> {
typeof(CustomFilter)
};
//Global authorization filter
x.AuthorizeData = new AuthorizeData(){
Policy = "PolicyName"
};
//Removes "Endpoints" or "Endpoint" string from route
//Converts auto generated route from /Image/GetImageEndpoint to /Image/GetImage
x.RemoveEndpointStringInRoute = true;
//The method name that will be taken and used as endpoint method.
x.DefaultEndpointMethodName = "Handle";
});
Since the automatic swagger generation will take class names as tags, it won't make sense to use default one.
builder.Services.AddSwaggerGen(c => {
//This will create tags from folder names
c.ConfigureMinimalApiTags();
});
Any objects that implement IBuilderServiceSetup and/or IApplicationSetup will be processed when the WebApplication is built. This happens once, when the application starts.
The following sample file (Authentication.cs) sets up azure AD authentication with the application.
public class AzureADAuthenticationSetup : IApplicationSetup, IBuilderServiceSetup
{
public int InitializationOrder { get; } = 1; // Initialization order only applies to IApplicationSetup setup
public void InitializeApplication(WebApplication app)
{
var azureAd = app.Configuration.GetSection("AzureAd").Get<AzureAd>();
if (azureAd != null) {
app.UseAuthentication();
app.UseAuthorization();
}
}
public void InitializeServices(WebApplicationBuilder builder)
{
var azureAd = builder.Configuration.GetSection("AzureAd").Get<AzureAd>();
if (azureAd != null)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options => { builder.Configuration.Bind("AzureAd", options); },
options => { builder.Configuration.Bind("AzureAd", options); });
}
}
This is a complete Program.cs file!
var builder = WebApplication.CreateBuilder(args);
//if using IBuilderServiceSetup
builder.UseBuilderSetup();
var app = builder.Build();
//if using IApplicationSetup
app.UseApplicationSetup();
//if using EndpointAttributes (Minimal API)
app.UseMinimalApiEndpoints();
app.Run();