2017-06-19 90 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