Minimal API ASP.NET core: is it possible to get HTTP verb inside of derived FlatValidator?

74 Views Asked by At

We want to try to increase performance in one microservice of our solution, that's why we have decided to try the FlatValidator in the part of the data validation. I'm new with such approach, at first glance it looks like very simple but I have to get an access to HttpContext into the derived class and it does not work.

public record class RateRequest(Guid RateId, string Metadata);

public class RateRequestValidator : FlatValidator<RateRequest>
{
    public RateRequestValidator(HttpContext httpContext)
    {
        if (httpContext.Request.Method == HttpMethods.Post)
        {
            ValidIf(m => m.RateId == Guid.Empty, 
                    m => $"Bad HTTP method ({httpContext.Request.Method}).", 
                    m => m.RateId);
        }
        else if (httpContext.Request.Method == HttpMethods.Put)
        {
            ValidIf(m => m.RateId != Guid.Empty, 
                    m => $"Bad HTTP method ({httpContext.Request.Method}).", 
                    m => m.RateId);
        }
    }
}

But it gives me the error: System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: System.Validation.IFlatValidator`1[RateRequest] Lifetime: Transient ImplementationType: RateRequestValidator'...

Please, help me to figure out this problem.

1

There are 1 best solutions below

0
Julia L On

Advice of @'Arthur Edgarov' was correct. Yes, the problem was not related to FlatValidator, the HttpContext can not be reached directly, only via IHttpContextAccessor.

// needs to register HttpContextAccessor
builder.Services.AddHttpContextAccessor();
builder.Services.AddFlatValidatorsFromAssembly(typeof(RateRequestValidator).Assembly);

// ......

public record class RateRequest(Guid RateId, string Metadata);

public class RateRequestValidator : FlatValidator<RateRequest>
{
    // and pass IHttpContextAccessor as parameter instead of HttpContext
    public RateRequestValidator(IHttpContextAccessor httpContextAccessor)
    {
        if (httpContextAccessor.HttpContext is HttpContext httpContext)
        {
            if (httpContext.Request.Method == HttpMethods.Post)
            {
                ValidIf(m => m.RateId == Guid.Empty, 
                        m => $"Bad HTTP method ({httpContext.Request.Method}).", 
                        m => m.RateId);
            }
            else if (httpContext.Request.Method == HttpMethods.Put)
            {
                ErrorIf(m => m.RateId == Guid.Empty,
                        m => $"Bad HTTP method ({httpContext.Request.Method}).", 
                        m => m.RateId);
            }
        }
    }
}