Szyszka947
Szyszka947

Reputation: 892

GetEndpoint() in middleware is always null

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

Answers (2)

AMunim
AMunim

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();

and this is my output: System.Exception: yes encryption
at StackAnswersASP.EncryptionMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in C:\Users\HP\source\repos\StackAnswersASP\StackAnswersASP\EncryptionMiddleware.cs:line 18

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

davidfowl
davidfowl

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

Related Questions