在Asp.net核心中使用Swagger进行流利的验证
问题描述:
我目前使用Fluent Validation
而不是Data Annotations
作为我的Web API,并使用swagger作为API文档。流畅的验证规则不反映在swagger模型中,因为我无法使用swagger模式筛选器配置流畅的验证规则。在Asp.net核心中使用Swagger进行流利的验证
This Blog对使用它与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>();
我试图按照这种解决方案;然而,我遇到了“InvalidOperationException:无法从根提供程序中解析'FluentValidation.IValidator'1 [MyClass]',因为它需要有限范围的服务'MyConfig'。”当工厂试图获得验证器时例外。我的验证器有时依赖于有限范围的服务(如配置)。直接调用API方法时,默认的ASP.NET Core DI和验证器可以正常工作,但由于某种原因,它在此处失败。你有没有碰到过这个? – wdspider
@wdspider在你没有流利的验证的情况下,你是否为你而工作? –
是的。如果我从swaggerGen选项中删除'options.SchemaFilter();'行(即不尝试集成流畅的验证规则);我成功地获得了一个生成的swagger.json文件以及正在运行的Swashbuckle UI。缺点是它没有显示任何验证信息,这就是为什么我首先找到这个解决方案的原因。 –
wdspider