2016-12-14 3 views
2

У меня есть контроллер WebAPI, который принимает двоичные пакеты и хранит их где-то. Поскольку эти пакеты могут стать довольно большими, я не хочу загружать их в память, добавляя параметр байтового массива, а скорее передавая поток.Как я могу сказать Swashbuckle, что содержание тела требуется?

Я нашел способ сделать это in this answer:

[HttpPost] 
[Route("Store/{projectId}")] 
public async Task Store(string projectId) 
{ 
    using (var stream = await this.Request.Content.ReadAsStreamAsync()) 
    { 
     await this.packageManager.StorePackageAsync(projectId, stream); 
    } 
} 

Это работает, я могу передавать файлы на контроллер через почтальона. Тем не менее, теперь я хочу создать документацию swagger с помощью Swashbuckle, и, конечно же, здесь не упоминается требуемое содержание тела.

Есть ли способ получить поток содержимого запроса, чтобы Swashbuckle знал об этом? Или есть ли атрибут, который я могу использовать, чтобы рассказать о требуемом контенте?

ответ

3

Для этого вам нужно сделать пару вещей.

Прежде всего вам нужно сообщить Swagger, что в теле есть параметр, содержащий двоичные данные. Затем вы должны сказать Swagger, что конечная точка потребляет двоичные данные (например, application/octet-stream).

Swashbuckle не поддерживает это из коробки. Но вы можете создавать собственные фильтры для расширения функциональности Swashbuckle. Обычно я делаю это создание настраиваемого атрибута для украшения метода, а затем создание настраиваемого фильтра для воздействия на этот атрибут.

В вашем случае это будет делать трюк:

Обычай атрибут

public class BinaryPayloadAttribute : Attribute 
{ 
    public BinaryPayloadAttribute() 
    { 
     ParameterName = "payload"; 
     Required = true; 
     MediaType = "application/octet-stream"; 
     Format = "binary"; 
    } 

    public string Format { get; set; } 

    public string MediaType { get; set; } 

    public bool Required { get; set; } 

    public string ParameterName { get; set; } 
} 

Обычай фильтр

public class BinaryPayloadFilter : IOperationFilter 
{ 
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 
    { 
     var attribute = apiDescription.GetControllerAndActionAttributes<BinaryPayloadAttribute>().FirstOrDefault(); 
     if (attribute == null) 
     { 
      return; 
     } 

     operation.consumes.Clear(); 
     operation.consumes.Add(attribute.MediaType); 

     operation.parameters.Add(new Parameter 
     { 
      name = attribute.ParameterName, 
      @in = "body", 
      required = attribute.Required, 
      type = "string", 
      format = attribute.Format 
     }); 
    } 
} 

Добавить фильтр конфигурации Swashbuckle

GlobalConfiguration.Configuration 
    .EnableSwagger(c => 
     { 
      // other configuration setting removed for brevity 
      c.OperationFilter<BinaryPayloadFilter>(); 
     }); 

Применение атрибута к вашему методу

[HttpPost] 
[BinaryPayload] 
[Route("Store/{projectId}")] 
public async Task Store(string projectId) 
{ 
    ... 
} 

В Swagger UI вы получите то:

Swagger UI

Смежные вопросы