2016-04-27 23 views
4

IFormFileプロパティを持つモデルをテストするためにswaggerをセットアップしようとしています。例えば 私はデフォルトの闊歩することにより、次のAPIメソッドAsp.Net Core swaggerヘルプページFor IFormFile

[HttpPost] 
public ApiResult<UserModel> SaveTestFileData([FromForm]TestPostFileArgs args) 
{ 
    var result = new UserModel() { Id = 1, Name = $"SaveTestFileData {args.UserId} company: {args.CompanyId}, file length: {args.CompanyFile.Length}" }; 
    return ApiResult.Success(result); 
} 

そして、私のパラメータモデル

public class TestPostFileArgs 
{ 
    public int UserId { get; set; } 
    public int? CompanyId { get; set; } 
    public IFormFile CompanyFile { get; set; } 
} 

を持っているが、私は次のOperationFilterを書いたこの問題を解決するために、それ Wrong swagger ui をテストすることはできませんヘルプページを生成します

public class FormFileOperationFilter: IOperationFilter 
{ 
    public void Apply(Operation operation, OperationFilterContext context) 
    { 
     if (operation.Parameters == null) 
      return; 

     var fileParamNames = context.ApiDescription.ActionDescriptor.Parameters 
      .SelectMany(x => x.ParameterType.GetProperties()) 
      .Where(x => x.PropertyType.IsAssignableFrom(typeof (IFormFile))) 
      .Select(x => x.Name) 
      .ToList(); 
     if (!fileParamNames.Any()) 
      return; 

     var paramsToRemove = new List<IParameter>(); 
     foreach (var param in operation.Parameters) 
     { 
      paramsToRemove.AddRange(from fileParamName in fileParamNames where param.Name.StartsWith(fileParamName + ".") select param); 
     } 
     paramsToRemove.ForEach(x => operation.Parameters.Remove(x)); 
     foreach (var paramName in fileParamNames) 
     { 
      var fileParam = new NonBodyParameter 
       { 
        Type = "file", 
        Name = paramName, 
        In = "formData" 
       }; 
      operation.Parameters.Add(fileParam); 
     } 
     foreach (IParameter param in operation.Parameters) 
     { 
      param.In = "formData"; 
     } 

     operation.Consumes = new List<string>() { "multipart/form-data" }; 
    } 
} 

これ以降、私はswaggeから期待していますr。 Correct swagger ui

今のところ、このソリューションは私にとっては効果的ですが、正しくはないと感じています。たぶん私はこれのためのいくつかの簡単な解決策が不足しています。また、このアプローチでは、Listや複雑なオブジェクトのプロパティをIFormFileやその他のもので処理することはありません。

+0

ありがとう、私はこれを探していた! – Andrii

答えて

1

私は同じ問題を抱えていて、あなたのソリューションは私を助けました。

IFormFileパラメータがネストされたパラメータではなく、アクションメソッドのメインパラメータであるため、私はOperationFilterを変更しました。

public class AddFileUploadParams : IOperationFilter 
{ 
    public void Apply(Operation operation, OperationFilterContext context) 
    { 
     if (operation.Parameters == null) 
      return; 

     var formFileParams = context.ApiDescription.ActionDescriptor.Parameters 
           .Where(x => x.ParameterType.IsAssignableFrom(typeof(IFormFile))) 
           .Select(x => x.Name) 
           .ToList(); ; 

     var formFileSubParams = context.ApiDescription.ActionDescriptor.Parameters 
      .SelectMany(x => x.ParameterType.GetProperties()) 
      .Where(x => x.PropertyType.IsAssignableFrom(typeof(IFormFile))) 
      .Select(x => x.Name) 
      .ToList(); 

     var allFileParamNames = formFileParams.Union(formFileSubParams); 

     if (!allFileParamNames.Any()) 
      return; 

     var paramsToRemove = new List<IParameter>(); 
     foreach (var param in operation.Parameters) 
     { 
      paramsToRemove.AddRange(from fileParamName in allFileParamNames where param.Name.StartsWith(fileParamName + ".") select param); 
     } 
     paramsToRemove.ForEach(x => operation.Parameters.Remove(x)); 
     foreach (var paramName in allFileParamNames) 
     { 
      var fileParam = new NonBodyParameter 
      { 
       Type = "file", 
       Name = paramName, 
       In = "formData" 
      }; 
      operation.Parameters.Add(fileParam); 
     } 
     foreach (IParameter param in operation.Parameters) 
     { 
      param.In = "formData"; 
     } 

     operation.Consumes = new List<string>() { "multipart/form-data" }; 
    } 
} 

スウェーガーを生成するのに、SwashBuckleを使用するとします。 swashBuckleがこれを処理するといいでしょう。たぶん私は時間が残っている場合は貢献します。

関連する問題