micro-elements / MicroElements.Swashbuckle.FluentValidation

Use FluentValidation rules instead of ComponentModel attributes
MIT License
379 stars 60 forks source link

Can it be used without AddFluentValidationAutoValidation? #127

Open leotuna opened 1 year ago

leotuna commented 1 year ago

I would like to manually sanitize and then validate the model.

With AddFluentValidationAutoValidation, validation occurs before it hits the Controller.

Can I use AddFluentValidationRulesToSwagger() without AddFluentValidationAutoValidation()?

aboryczko commented 1 year ago

I've added the following single dependency: services.TryAddScoped<IValidatorFactory, ServiceProviderValidatorFactory>(); but this is only a workaround until they remove IValidatorFactory (currently deprecated) from the FluentValidation library

petriashev commented 1 year ago

You can implement your own IValidatorRegistry see: https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation/blob/master/src/MicroElements.OpenApi.FluentValidation/FluentValidation/IValidatorRegistry.cs Register IValidatorRegistry before AddFluentValidationRulesToSwagger

cremor commented 1 year ago

See #111

AJax2012 commented 1 year ago

@leotuna

I don't know if you ever got this resolved, but I was able to get it working without using AddFluentValidationAutoValidation using the following:

services.AddSwaggerGen(); // setup your desired config

builder.Services.AddValidatorsFromAssemblyContaining<Program>(); // adjust for location of validators assembly
builder.Services.AddFluentValidationClientsideAdapters(); // this is the important part - read below.
builder.Services.AddFluentValidationRulesToSwagger();

As noted in the code snippet, the important part is adding AddFluentValidationClientsideAdapters from the FluentValidation.AspNetCore library. This probably explains the reason it's necessary a bit better than I can: https://docs.fluentvalidation.net/en/latest/aspnet.html#clientside-validation.

I can send a bit fuller of an example if that didn't work for you, but I think that should be all you need.

m7jakob commented 12 months ago

The workaround posted by aboryczko worked for me as well. Using ClientSide- and AutoValidation did not work for me because I explicitly do not want to hook into the aspnetcore model validation pipeline.

I am using MediatR and I have a Validation behavior which handles all model validation for me.

Tri125 commented 1 month ago

In our ASP.NET Core controller-base API on .NET 8.0 all we had to do is call builder.Services.AddFluentValidationRulesToSwagger(); and register our AbstractValidator to the DI container.

public class MyTypeValidator : AbstractValidator<MyType>
{
    public MyTypeValidator()
    {
        RuleFor(dto => dto.Amount)
            .InclusiveBetween(0, 100);
    }
}

services.AddSingleton<IValidator<MyType>, MyTypeValidator>();

There's a bit of a pitfall for collections of complex types. If you combine RuleForEach with SetValidator i.e. RuleForEach(x => x.Orders).SetValidator(new MyTypeValidator()) then you might not think about registering the validator in the DI container.