webentwicklung-frage-antwort-db.com.de

Swashbuckle Swagger - Wie werden Inhaltstypen kommentiert?

Wie kommentiere ich meine ASP.NET-WebAPI-Aktionen, damit die Swagger-Metadaten die Inhaltstypen enthalten, die meine Ressourcen unterstützen?

Insbesondere möchte ich, dass die Dokumentation zeigt, dass eine meiner Ressourcen den 'ursprünglichen' application/json und application/xml zurückgeben kann, aber jetzt auch ein neues Format, application/vnd.blah+json oder +xml, zurückgibt.

13
Luke Puplett

Was Sie tun müssen, ist Folgendes: Swagger spec: Sie müssen den Antworttyp der Liste der Antworttypen für diesen Vorgang hinzufügen

"produces": [
            "application/json",
            "text/json"
            ],

Dies kann mit einem OperationFilter erfolgen

Pseudo-Code eingehend !!!

public class CustomResponseType : IOperationFilter
{        
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {            
            if (operation.operationId == "myCustomName")
            {
                operation.produces.Add("application/vnd.blah+json");
            }            
    }      
}

die OperationId kann über die Annotation [SwaggerOperation("myCustomName")] festgelegt werden.

Wenden Sie dann den operationsFilter in der Datei swaggerConfig.cs an

c.OperationFilter<CustomResponseType>();

Hinweis: Anstelle von operation.operationId == "myCustomName" können Sie dies grundsätzlich für eine bestimmte Route oder etwas anderes tun. ApiDescription liefert eine Fülle von Informationen zum Kontext.

8
VisualBean

Antwort von @ VisualBean erweitern 

In der API-Methode eines Controllers können Sie den folgenden Code verwenden, um ein Attribut wie folgt festzulegen:

[SwaggerResponseContentType(responseType:"application/pdf", Exclusive=true)]
public HttpResponseMessage GetAuthorityForm(string id)
{
....

Hinweis: 'Exclusive = true' entfernt alle anderen Inhaltstypen. Andernfalls wird bei Verwendung des neuen Attributs ein neuer Antwort-Inhaltstyp in der Dropdown-Liste der Swagger-Benutzeroberfläche hinzugefügt. Es wird NICHT Ihren Controller oder die API ändern, sondern nur die Dokumentation.

SwaggerConfig.cs

 GlobalConfiguration.Configuration
            .EnableSwagger(c =>
 // Set filter to apply Custom Content Types to operations
 //
 c.OperationFilter<ResponseContentTypeOperationFilter>();

SwaggerReponseContentTypeAttribute.cs

/// <summary>
/// SwaggerResponseContentTypeAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class SwaggerResponseContentTypeAttribute : Attribute
{
    /// <summary>
    /// SwaggerResponseContentTypeAttribute
    /// </summary>
    /// <param name="responseType"></param>
    public SwaggerResponseContentTypeAttribute(string responseType)
    {
        ResponseType = responseType;
    }
    /// <summary>
    /// Response Content Type
    /// </summary>
    public string ResponseType { get; private set; }

    /// <summary>
    /// Remove all other Response Content Types
    /// </summary>
    public bool Exclusive { get; set; }
}

ResponseContentTypeOperationFilter.cs

public class ResponseContentTypeOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerResponseContentTypeAttribute>().FirstOrDefault();

        if (requestAttributes != null)
        {
            if (requestAttributes.Exclusive)
                operation.produces.Clear();

            operation.produces.Add(requestAttributes.ResponseType);
        }
    }
}
36
OzBob

Die Antwort von @ OzBob setzt voraus, dass Sie einer Methode nur ein einzelnes Attribut hinzufügen möchten. Wenn Sie mehrere Inhaltstypen für dieselbe Methode hinzufügen und dokumentieren möchten, können Sie Folgendes verwenden:

SwaggerReponseContentTypeAttribute.cs

/// <summary>
/// SwaggerResponseContentTypeAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SwaggerResponseContentTypeAttribute : Attribute
{
    /// <summary>
    /// SwaggerResponseContentTypeAttribute
    /// </summary>
    /// <param name="responseType"></param>
    public SwaggerResponseContentTypeAttribute(string responseType)
    {
        ResponseType = responseType;
    }
    /// <summary>
    /// Response Content Type
    /// </summary>
    public string ResponseType { get; private set; }

    /// <summary>
    /// Remove all other Response Content Types
    /// </summary>
    public bool Exclusive { get; set; }
}

ResponseContentTypeOperationFilter.cs

public class ResponseContentTypeOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerResponseContentTypeAttribute>();

        foreach (var requestAttribute in requestAttributes)
        {
            if (requestAttribute.Exclusive)
            {
                operation.produces.Clear();
            }
            operation.produces.Add(requestAttribute.ResponseType);
        }
    }
}

Wenn Sie mehrere Attribute für dieselbe Methode verwenden und die vorhandenen Inhaltstypen ersetzen möchten, sollten Sie Exclusive = true nur für das erste Attribut festlegen. Andernfalls erhalten Sie nicht alle Attribute in die Dokumentation.

5
bjorgvin

Folgen Sie der Antwort von OzBob. Seit Swashbuckle 4.0.x müssen Sie möglicherweise den Operationsfiltercode leicht aktualisieren:

ResponseContentTypeOperationFilter.cs

using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Linq;

public class ResponseContentTypeOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (!context.ApiDescription.TryGetMethodInfo(out var methodInfo))
        {
            return;
        }
        var requestAttributes = methodInfo.GetCustomAttributes(true).OfType<SwaggerResponseContentTypeAttribute>().FirstOrDefault();

        if (requestAttributes != null)
        {
            if (requestAttributes.Exclusive)
                operation.Produces.Clear();

            operation.Produces.Add(requestAttributes.ResponseType);
        }
    }
}
2
Grubl3r