簡體   English   中英

在 Asp.net Core 中使用 Swagger 進行流暢驗證

[英]Fluent Validation with Swagger in Asp.net Core

我目前在 Web api 中使用Fluent Validation而不是Data Annotations ,並在 API 文檔中使用 swagger。 流暢的驗證規則未反映在 swagger 模型中,因為我無法使用 swagger 模式過濾器配置流暢的驗證規則。

這個博客對在 ASP.net MVC 中使用它有很好的解釋。 但我無法配置它以在 ASP.net Core 中使用它。

到目前為止,我已經嘗試了以下代碼,但我無法獲得驗證器類型。

services.AddSwaggerGen(options => options.SchemaFilter<AddFluentValidationRules>());

public class AddFluentValidationRules : ISchemaFilter
{
    public void Apply(Schema model, SchemaFilterContext context)
    {
        model.Required = new List<string>();
        var validator = GetValidator(type); // How?
        var validatorDescriptor = validator.CreateDescriptor();

        foreach (var key in model.Properties.Keys)
        {
            foreach (var propertyValidator in validatorDescriptor.GetValidatorsForMember(key))
            {
                 // Add to model properties as in blog
            }
        }
    }
}

我已經根據 Mujahid Daud Khan 的回答創建了 github 項目和 nuget 包。 我進行了重新設計以支持可擴展性並支持其他驗證器。

github: https : //github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation

nuget: https ://www.nuget.org/packages/MicroElements.Swashbuckle.FluentValidation

注意:對於 WebApi,請參閱: https : //github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation.WebApi

支持的驗證器

  • INotNullValidator (NotNull)
  • INotEmptyValidator (NotEmpty)
  • ILengthValidator(長度、最小長度、最大長度、精確長度)
  • IRegularExpressionValidator(電子郵件,匹配)
  • IComparisonValidator(GreaterThan、GreaterThanOrEqual、LessThan、LessThanOrEqual)
  • IBetweenValidator (InclusiveBetween, ExclusiveBetween)

用法

1.在你的web項目中引用包:

<PackageReference Include="FluentValidation.AspNetCore" Version="7.5.2" />
<PackageReference Include="MicroElements.Swashbuckle.FluentValidation" Version="0.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.3.0" />

2.更改Startup.cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        // Adds fluent validators to Asp.net
        .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<CustomerValidator>());

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        // Adds fluent validation rules to swagger
        c.AddFluentValidationRules();
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app
        .UseMvc()
        // Adds swagger
        .UseSwagger();

    // Adds swagger UI
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
}

Swagger 示例模型和驗證器

public class Sample
{
    public string PropertyWithNoRules { get; set; }

    public string NotNull { get; set; }
    public string NotEmpty { get; set; }
    public string EmailAddress { get; set; }
    public string RegexField { get; set; }

    public int ValueInRange { get; set; }
    public int ValueInRangeExclusive { get; set; }
}

public class SampleValidator : AbstractValidator<Sample>
{
    public SampleValidator()
    {
        RuleFor(sample => sample.NotNull).NotNull();
        RuleFor(sample => sample.NotEmpty).NotEmpty();
        RuleFor(sample => sample.EmailAddress).EmailAddress();
        RuleFor(sample => sample.RegexField).Matches(@"(\d{4})-(\d{2})-(\d{2})");

        RuleFor(sample => sample.ValueInRange).GreaterThanOrEqualTo(5).LessThanOrEqualTo(10);
        RuleFor(sample => sample.ValueInRangeExclusive).GreaterThan(5).LessThan(10);
    }
}

隨意添加問題!

搜索后,我終於發現我需要IValidationFactory驗證器實例。

public class AddFluentValidationRules : ISchemaFilter
{
    private readonly IValidatorFactory _factory;

    /// <summary>
    ///     Default constructor with DI
    /// </summary>
    /// <param name="factory"></param>
    public AddFluentValidationRules(IValidatorFactory factory)
    {
        _factory = factory;
    }

    /// <summary>
    /// </summary>
    /// <param name="model"></param>
    /// <param name="context"></param>
    public void Apply(Schema model, SchemaFilterContext context)
    {

        // use IoC or FluentValidatorFactory to get AbstractValidator<T> instance
        var validator = _factory.GetValidator(context.SystemType);
        if (validator == null) return;
        if (model.Required == null)
            model.Required = new List<string>();

        var validatorDescriptor = validator.CreateDescriptor();
        foreach (var key in model.Properties.Keys)
        {
            foreach (var propertyValidator in validatorDescriptor
                .GetValidatorsForMember(ToPascalCase(key)))
            {
                if (propertyValidator is NotNullValidator 
                  || propertyValidator is NotEmptyValidator)
                    model.Required.Add(key);

                if (propertyValidator is LengthValidator lengthValidator)
                {
                    if (lengthValidator.Max > 0)
                        model.Properties[key].MaxLength = lengthValidator.Max;

                    model.Properties[key].MinLength = lengthValidator.Min;
                }

                if (propertyValidator is RegularExpressionValidator expressionValidator)
                    model.Properties[key].Pattern = expressionValidator.Expression;

                // Add more validation properties here;
            }
        }
    }

    /// <summary>
    ///     To convert case as swagger may be using lower camel case
    /// </summary>
    /// <param name="inputString"></param>
    /// <returns></returns>
    private static string ToPascalCase(string inputString)
    {
        // If there are 0 or 1 characters, just return the string.
        if (inputString == null) return null;
        if (inputString.Length < 2) return inputString.ToUpper();
        return inputString.Substring(0, 1).ToUpper() + inputString.Substring(1);
    }
}

並將此類添加到 swaggerGen 選項

options.SchemaFilter<AddFluentValidationRules>();
  1. 安裝 Nuget 包: MicroElements.Swashbuckle.FluentValidation

  2. 添加到配置services.AddFluentValidationRulesToSwagger();services.AddFluentValidationRulesToSwagger();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM