2017-06-19 89 views
3

我目前使用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 
      } 
     } 
    } 
} 

回答

1

搜索我终于想通了,我需要为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>(); 
+0

我试图按照这种解决方案;然而,我遇到了“InvalidOperationException:无法从根提供程序中解析'FluentValidation.IValidator'1 [MyClass]',因为它需要有限范围的服务'MyConfig'。”当工厂试图获得验证器时例外。我的验证器有时依赖于有限范围的服务(如配置)。直接调用API方法时,默认的ASP.NET Core DI和验证器可以正常工作,但由于某种原因,它在此处失败。你有没有碰到过这个? – wdspider

+0

@wdspider在你没有流利的验证的情况下,你是否为你而工作? –

+0

是的。如果我从swaggerGen选项中删除'options.SchemaFilter ();'行(即不尝试集成流畅的验证规则);我成功地获得了一个生成的swagger.json文件以及正在运行的Swashbuckle UI。缺点是它没有显示任何验证信息,这就是为什么我首先找到这个解决方案的原因。 – wdspider