Asp.net-Core
在 Asp.net Core 中使用 Swagger 進行流暢的驗證
我目前正在使用
Fluent Validation而不是Data Annotations用於我的 Web api,並將 swagger 用於 API 文件。流暢的驗證規則沒有反映在 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 } } } }
經過搜尋,我終於發現我需要
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>();
我根據 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); } }隨意添加問題!