[英]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
<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" />
// 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");
});
}
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>();
安裝 Nuget 包: MicroElements.Swashbuckle.FluentValidation
添加到配置services.AddFluentValidationRulesToSwagger();
: services.AddFluentValidationRulesToSwagger();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.