web-dev-qa-db-ja.com

Swashbuckle Swagger-コンテンツタイプに注釈を付ける方法

リソースをサポートするコンテンツタイプがswaggerメタデータに含まれるように、ASP.NET WebAPIアクションに注釈を付けるにはどうすればよいですか?

具体的には、リソースの1つが「元の」application/jsonおよびapplication/xmlを返すことができるが、新しい形式application/vnd.blah+jsonまたは+xmlを返すことをドキュメントに示す必要があります。

15
Luke Puplett

@VisualBeanの答えを拡張する

コントローラのAPIメソッドでは、次のコードを使用して次のような属性を設定できます。

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

注:「Exclusive = true」は他のすべてのコンテンツタイプを削除します。そうでない場合、新しい属性を使用すると、Swagger UIドロップダウンに新しいレスポンスコンテンツタイプが追加されます。コントローラーやAPIを変更するのはドキュメントだけではありません。

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

@OzBobの答えは、メソッドに1つの属性のみを追加することを前提としています。同じメソッドに対して複数のコンテンツタイプを追加して文書化する場合は、次を使用できます。

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

同じメソッドに複数の属性があり、既存のコンテンツタイプを置き換える場合は、Exclusive = true最初の属性のみ。そうしないと、すべての属性をドキュメントに取得できません。

5
bjorgvin

OzBobの答えに従ってください。 Swashbuckle 4.0.x以降、操作フィルターコードをわずかに更新する必要がある場合があります。

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