【问题标题】:.NET Core 2.0 Web API - How to add a custom header parameter in Swagger.NET Core 2.0 Web API - 如何在 Swagger 中添加自定义标头参数
【发布时间】:2018-05-13 08:28:04
【问题描述】:

根据标题 - 我找到了如何使用常规 .NET 执行此操作的示例

例如: Web Api How to add a Header parameter for all API in Swagger

但是,我找不到任何示例或文档来说明如何在使用 .NET Core 2.0 时完成同样的事情。

【问题讨论】:

  • 您是否尝试过实现 IOperationFilter?

标签: .net-core swagger swashbuckle openapi.net


【解决方案1】:

swagger/OpenApi请求头和响应头有两种类型的头。

请求标头

请求标头易于实现,您只需像这样装饰您的控制器和/或操作:

[Route("api/[controller]")]
public class RequestHeadersController : Controller
{
    [FromHeader(Name = "x-my-controller-wide-header")]
    public string MyControllerWideHeader { get; set; }

    [HttpGet]
    public string Get([FromHeader(Name = "x-my-operation-header")]string myOperationHeader)
    {
        return myOperationHeader;
    }
}

Swashbuckle.AspNetCore 将自动选取使用 FromHeaderAttribute 定义的任何标头并将其应用于 swagger 文档。

响应标头

在 Asp.Net Core 或 Swashbuckle 中没有指定响应标头的声明方式,因此您必须手动执行此操作。

下面的示例将返回一个自定义标题名称 x-my-header。

[Route("api/[controller]")]
public class ResponseHeadersController : Controller
{
    [HttpGet]
    public string Get()
    {
        HttpContext.Response.Headers["x-my-header"] = "header value";

        return "value";
    }
}

我们现在需要指示 swagger 包含响应标头。这是通过 IOperationFilter 完成的,请参阅Swashbuckle documentation 了解过滤器的工作原理。过滤器可以全局或按操作应用,但是您不能通过将参数传递到其构造函数来自定义行为,请按照声明过滤器的方式(仅按类型)。 因此,您必须为每个返回一个或多个响应标头的 API 方法编写一个操作过滤器。或者,您可以定义一个属性来声明操作的响应标头。

public enum HeaderResponseType { String, Number }

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class ProducesResponseHeaderAttribute : Attribute
{
    public ProducesResponseHeaderAttribute(string name, int statusCode)
    {
        Name = name ?? throw new ArgumentNullException(nameof(name));
        StatusCode = statusCode;
        Type = HeaderResponseType.String;
    }

    public string Name { get; set; }
    public int StatusCode { get; set; }
    public HeaderResponseType Type { get; set; }
    public string Description { get; set; }
}

这使我们能够为每个响应代码声明一个或多个标头。

    [HttpGet]
    [ProducesResponseHeader("x-my-header", (int)HttpStatusCode.OK)]
    public string Get()
    {
        HttpContext.Response.Headers["x-my-header"] = "header value";

        return "string";
    }

现在我们有了一个定义我们意图的属性,我们可以制作一个通用操作过滤器。

public class ResponseHeadersFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        // Get all response header declarations for a given operation
        var actionResponsesWithHeaders = context.ApiDescription.ActionAttributes()
            .OfType<ProducesResponseHeaderAttribute>()
            .ToArray();

        if (!actionResponsesWithHeaders.Any())
            return;

        foreach (var responseCode in operation.Responses.Keys)
        {
            // Do we have one or more headers for the specific response code
            var responseHeaders = actionResponsesWithHeaders.Where(resp => resp.StatusCode.ToString() == responseCode);
            if (!responseHeaders.Any())
                continue;

            var response = operation.Responses[responseCode];
            if (response.Headers == null)
                response.Headers = new Dictionary<string, Header>();

            foreach (var responseHeader in responseHeaders)
            {
                response.Headers[responseHeader.Name] = new Header
                {
                    Type = responseHeader.Type.ToString(),
                    Description = responseHeader.Description
                };
            }
        }
    }
}

我们现在需要做的就是将操作过滤器连接到 swagger 生成。

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    c.OperationFilter<ResponseHeadersFilter>();
};

我希望这足以让你继续前进。

【讨论】:

  • 为这个方法添加多个头值怎么样:[FromHeader(Name = "HeaderKey")]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2021-11-27
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多