2016-12-14 4 views
2

J'ai un contrôleur WebAPI qui accepte les paquets binaires et les stocke quelque part. Comme ces paquets peuvent devenir assez volumineux, je ne veux pas les charger en mémoire en ajoutant un paramètre de tableau d'octets, mais plutôt transmettre un flux.Comment puis-je dire à Swashbuckle que le contenu du corps est nécessaire?

J'ai trouvé une façon de le faire 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); 
    } 
} 

Cela fonctionne, je peux envoyer des fichiers au contrôleur en utilisant Postman. Cependant, je veux maintenant générer de la documentation Swagger avec Swashbuckle et bien sûr, le contenu du corps requis n'est pas mentionné là.

Existe-t-il un moyen d'obtenir un flux du contenu de la requête afin que Swashbuckle le sache? Ou y a-t-il un attribut que je peux utiliser pour le dire sur le contenu requis?

Répondre

3

Pour ce faire, vous devez faire quelques choses.

D'abord, vous devez dire à Swagger qu'il existe dans le corps un paramètre contenant des données binaires. Ensuite, vous devez dire à Swagger que le point final consomme des données binaires (par exemple application/octet-stream).

Le système Swashbuckle ne supporte pas ce type de boîtier. Mais vous pouvez créer des filtres personnalisés pour étendre les fonctionnalités de Swashbuckle. Ce que je fais habituellement est de créer un attribut personnalisé pour décorer une méthode, puis créer un filtre personnalisé pour agir sur cet attribut.

Dans votre cas, ce serait faire l'affaire:

L'attribut personnalisée

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; } 
} 

Le filtre personnalisé

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 
     }); 
    } 
} 

Ajouter le filtre à la configuration Swashbuckle

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

Appliquer l'attribut à votre méthode

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

dans l'interface utilisateur Swagger vous obtenez alors:

Swagger UI