如何对ASP.NET WebAPI操作进行注释,以便swagger元数据包含我的资源支持的内容类型?
具体来说,我希望文档显示我的一个资源可以返回“原始”文件。 application/json
和application/xml
现在也会返回新格式application/vnd.blah+json
或+xml
。
答案 0 :(得分:38)
扩展@ VisualBean的答案
在Controller的API方法中,您可以使用以下代码来设置属性,如:
[SwaggerResponseContentType(responseType:"application/pdf", Exclusive=true)]
public HttpResponseMessage GetAuthorityForm(string id)
{
....
注意:'Exclusive = true'将删除所有其他内容类型,否则使用新属性将在Swagger UI下拉列表中添加新的响应内容类型。它不会仅仅修改文档中的Controller或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);
}
}
}
答案 1 :(得分:10)
你需要做的是这个; 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提供了大量有关上下文的信息。
答案 2 :(得分:5)
@ OzBob的回答假设您只想向方法添加单个属性。如果要为同一方法添加和记录多个内容类型,可以使用以下内容:
<强> 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
。否则,您将无法获得文档中的所有属性。
答案 3 :(得分:3)
跟随OzBob的回答。从Swashbuckle 4.0.x开始,您可能需要稍微更新操作过滤器代码:
ResponseContentTypeOperationFilter.cs
<input type="password" pattern="[0-9].{6,}[A-Z]" />