Reputation: 892
I have Middleware as below:
public class XChaCha20Poly1305EncryptionMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var isEncryptionEnabled = context.GetEndpoint().Metadata.Any(m => m is XChaCha20Poly1305EncryptionAttribute);
if(isEncryptionEnabled)
Console.WriteLine("Test 1");
else Console.WriteLine("Test 2");
await next(context);
}
}
And Program.cs:
services.AddTransient<XChaCha20Poly1305EncryptionMiddleware>();
services.AddControllersWithViews();
var app = builder.Build();
app.UseRouting();
app.UseMiddleware<XChaCha20Poly1305EncryptionMiddleware>();
But I always get exception that context.GetEndpoint()
in middleware is null. I'm using NET 6. So how can I check method attributes in middleware? Is this now possible? I've used this HansElsen answer but it doesn't work for me: asp.net core check route attribute in middleware
Upvotes: 1
Views: 4139
Reputation: 1171
I created a sample method attribute and decorated my action endpoint, this is how I check in my middleware
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var endpoint = context
?.GetEndpoint()
?.Metadata
?.GetMetadata<ControllerActionDescriptor>();
var encryptionEnabled = endpoint?.MethodInfo?.GetCustomAttribute<EncryptionAttribute>();
if (encryptionEnabled is null)
throw new Exception("no encryption");
else
throw new Exception("yes encryption");
await next(context);
}
and how I register my middleware
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<EncryptionMiddleware>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseMiddleware<EncryptionMiddleware>();
app.MapControllers();
app.Run();
My custom attribute
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class EncryptionAttribute: Attribute
{
}
and my controller
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
[Encryption]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
Upvotes: 3
Reputation: 38854
You don't need the call to UseRouting, nor the call to UseEndpoints, those are implicit with the new host. Endpoint selection happens when there's a route match (or manually set by other code but by default, routing is the only component that does it). What does your other code look like? I don't see any routes defined and I'm not sure what URL is being requested.
GetEndpoint() is null because there is no endpoint.
Upvotes: 4