2017-06-02 24 views
1

我想要一個自定義屬性來將數據解析爲流並且可以使用Swagger進行測試。Swagger不識別具有自定義屬性的WebAPI控制器參數[FromContent]

因此,我創建控制器從POST體寫着:

[SwaggerOperation("Create")] 
[SwaggerResponse(HttpStatusCode.Created)] 
public async Task<string> Post([FromContent]Stream contentStream) 
{ 
    using (StreamReader reader = new StreamReader(contentStream, Encoding.UTF8)) 
    { 
     var str = reader.ReadToEnd(); 
     Console.WriteLine(str); 
    } 
    return "OK"; 
} 

如何定義數據流,因此在揚鞭UI是可見的?

這是我實現FromContent屬性和ContentParameterBinding結合:

public class ContentParameterBinding : HttpParameterBinding 
{ 
    private struct AsyncVoid{} 
    public ContentParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor) 
    { 

    } 

    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, 
               HttpActionContext actionContext, 
               CancellationToken cancellationToken) 
    { 
     var binding = actionContext.ActionDescriptor.ActionBinding; 

     if (binding.ParameterBindings.Length > 1 || 
      actionContext.Request.Method == HttpMethod.Get) 
     { 
      var taskSource = new TaskCompletionSource<AsyncVoid>(); 
      taskSource.SetResult(default(AsyncVoid)); 
      return taskSource.Task as Task; 
     } 

     var type = binding.ParameterBindings[0].Descriptor.ParameterType; 

     if (type == typeof(HttpContent)) 
     { 
      SetValue(actionContext, actionContext.Request.Content); 
      var tcs = new TaskCompletionSource<object>(); 
      tcs.SetResult(actionContext.Request.Content); 
      return tcs.Task; 
     } 
     if (type == typeof(Stream)) 
     { 
      return actionContext.Request.Content 
      .ReadAsStreamAsync() 
      .ContinueWith((task) => 
      { 
       SetValue(actionContext, task.Result); 
      }); 
     } 

     throw new InvalidOperationException("Only HttpContent and Stream are supported for [FromContent] parameters"); 
    } 
} 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] 
public sealed class FromContentAttribute : ParameterBindingAttribute 
{ 
    public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter) 
    { 
     if (parameter == null) 
      throw new ArgumentException("Invalid parameter"); 

     return new ContentParameterBinding(parameter); 
    } 
} 

更新

當我創建Stream使用[FromBody]是顯示正確揚鞭,但Stream沒有啓動, ==null

[SwaggerOperation("Create")] 
[SwaggerResponse(HttpStatusCode.Created)] 
public async Task<string> Post([FromBody]Stream contentStream) 
{ 
    using (StreamReader reader = new StreamReader(contentStream, Encoding.UTF8)) 
    { 
     var str = reader.ReadToEnd(); 
     Console.WriteLine(str); 
    } 
    return "OK"; 
} 

Good Post

所以我想有相同的用戶界面,但與我的自定義屬性這讓是我有從內容Stream

隨着我的自定義屬性就說明沒有TextArea的參數,但可以用郵差進行測試和正常工作和StreamBad Post

+0

你如何想展示它?哪裏有問題?你應該澄清什麼輸出你期望 – Marusyk

+0

@MegaTron我試圖添加測試的帖子,其中流已經從內容正文創建,我會添加示例和圖片 –

+0

整個參數綁定的東西似乎是一個很大的工作避免在控制器方法中執行'var stream = await this.Request.Content.ReadAsStreamAsync()'。 –

回答

1

繼承FormatterParameterBinding類的綁定:

public class ContentParameterBinding : FormatterParameterBinding 
{ 
    public ContentParameterBinding(HttpParameterDescriptor descriptor) 
      : base(descriptor, 
        descriptor.Configuration.Formatters, 
        descriptor.Configuration.Services.GetBodyModelValidator()) 
    { 
    } 

    //your code 
} 
+0

謝謝你的幫助! –

相關問題