Swashbuckle Swagger - 如何注释内容类型?

Swashbuckle Swagger - How to annotate content types?

如何注释我的 ASP.NET WebAPI 操作,以便 swagger 元数据包含我的资源支持的内容类型?

具体来说,我希望文档显示我的资源之一可以 return 'original' application/jsonapplication/xml 但现在 return 是新格式,application/vnd.blah+json+xml.

你需要做的是这个; Swagger 规范: 您需要将您的响应类型添加到该操作的响应类型列表中:

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

这可以通过 OperationFilter 来完成。

伪代码来袭!!!

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

可以通过[SwaggerOperation("myCustomName")]注解设置OperationId。

然后在 swaggerConfig.cs:

中应用 operationsFilter
c.OperationFilter<CustomResponseType>();

注意: 而不是 operation.operationId == "myCustomName" 您基本上可以针对特定路线或其他任何内容进行操作。 ApiDescription 提供了很多关于上下文的信息。

扩展 .

在控制器的 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>();

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

假定您只想向方法添加一个属性。如果要为同一方法添加和记录多个内容类型,可以使用以下方法:

SwaggerResponseContentTypeAttribute.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。否则,您将无法将所有属性都放入文档中。

关注 。从 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);
        }
    }
}