micro-elements / MicroElements.Swashbuckle.FluentValidation

Use FluentValidation rules instead of ComponentModel attributes
MIT License
376 stars 55 forks source link

Validation rules don't show in swagger when using Min API #123

Open jxwaters opened 1 year ago

jxwaters commented 1 year ago

I am using dotnet 7 minapi, and I have fluent validation that does work on my endpoints, as well as working swagger docs. However, the swagger docs do not pick up the rules from my validators. For instance, the Create User API has this rule:

public class CreteUserValidator : AbstractValidator<CreateUserDTO>
{
    public CreteUserValidator()
    {
        RuleFor(x => x.FirstName).NotEmpty().MaximumLength(100);
        RuleFor(x => x.LastName).NotEmpty().MaximumLength(100);
        RuleFor(x => x.Email).NotEmpty().MaximumLength(256).EmailAddress();
        RuleFor(x => x.PhoneNumber).MaximumLength(100);
    }
}

I see it working if I omit email:

image

But the information is not in Swagger:

image

The validators are added here:

srv.AddValidatorsFromAssemblyContaining<CreteUserValidator>(ServiceLifetime.Singleton);

And to Swagger here (later on):


    private static IServiceCollection AddSwagger(this IServiceCollection srv)
    {
        srv.AddEndpointsApiExplorer();
        srv.AddSwaggerGen(
            options =>
            {
                options.MapType<decimal>(() => new OpenApiSchema { Type = "number", Format = "decimal" });
                options.AddSecurityDefinition(
                    JwtBearerDefaults.AuthenticationScheme,
                    new OpenApiSecurityScheme
                    {
                        Description =
                            "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                        Name = "Authorization",
                        In = ParameterLocation.Header,
                        Type = SecuritySchemeType.ApiKey,
                        Scheme = JwtBearerDefaults.AuthenticationScheme
                    });

                options.AddSecurityRequirement(
                    new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme
                                },
                                Scheme = "oauth2",
                                Name = JwtBearerDefaults.AuthenticationScheme,
                                In = ParameterLocation.Header,
                            },
                            new List<string>()
                        }
                    });
                options.SwaggerDoc(Constants.SwaggerDocVersion,
                    new OpenApiInfo
                    {
                        Title = "TrailheadTechnology API", Version = Constants.SwaggerDocVersion, Description = "Documents the REST API"
                    });

                options.IncludeXmlComments(Assembly.GetExecutingAssembly().Location.Replace("dll", "xml"), true);
                options.IncludeXmlComments(typeof(TokenRequest).Assembly.Location.Replace("dll", "xml"));

            }).AddSwaggerGenNewtonsoftSupport(); // explicit opt-in

        srv.AddFluentValidationRulesToSwagger();

        return srv;
    }
petriashev commented 1 year ago

Hello! What version of package do you use? Please try 6.0.0-beta.3 (I added minimal API example)

Palpie commented 1 year ago

The minimal API example doesn't look like a minimal API. It still uses controllers. An example minimal API would be:

var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");

app.Run();
leandrobattochio commented 1 year ago

Hello! What version of package do you use? Please try 6.0.0-beta.3 (I added minimal API example)

Don't know what you did, but it solved my issue. Thanks