Web Api如何在Swagger中为所有API添加Header参数

16 c# asp.net-web-api swagger swagger-ui

我搜索了添加请求标头参数的可能方法,该参数将自动添加到我的每个方法中,web-api但我找不到清楚的方法.

在搜索时我发现该方法OperationFilter()必须对此做些什么.

Ram*_*usa 32

是的,你可以通过继承来做到这一点 IOperationFilter

你可以在这里找到GitHub上的答案:AddRequiredHeaderParameter

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            operation.Parameters = new List<IParameter>();

        operation.Parameters.Add(new NonBodyParameter
            {
                Name = "X-User-Token",
                In = "header",
                Type = "string",
                Required = false
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

然后转到您的SwaggerConfig.cs文件并在以下AddSwaggerGen部分添加以下内容:

c.OperationFilter<AddRequiredHeaderParameter>();
Run Code Online (Sandbox Code Playgroud)

重建,享受.


Wil*_*che 12

用户“ G T”写的是正确的,但不适用于Swagger5。我们进行了一些新更改:

从:Operation到:OpenApiOperation

从:IParameter到:OpenApiParameter

从:NonBodyParameter到:OpenApiParameter,最重要的是...

从:Type = "string"到:Schema = new OpenApiSchema { Type = "String" }

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace MyAPI
{
    public class AuthorizationHeaderParameterOperationFilter: IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
            var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
            var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);

            if (isAuthorized && !allowAnonymous)
            {
                if (operation.Parameters == null)
                    operation.Parameters = new List<OpenApiParameter>();

                operation.Parameters.Add(new OpenApiParameter 
                {
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Description = "access token",
                    Required = true,
                    Schema = new OpenApiSchema
                    {
                        Type = "String",
                        Default = new OpenApiString("Bearer ")
                    }
                });
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并在Startup => ConfigureServices(

c.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
Run Code Online (Sandbox Code Playgroud)

  • 将 `Type = "String"` 更改为 `"Type = "string"` 让 SwaggerUI 再次使用 `required = true` 属性! (4认同)
  • 只是补充一下,我的控制器操作使用的是 AuthorizeAttribute,并且上面的代码不起作用,因为 isAuthorized 始终为 false。我也添加了对此的检查,并且它有效: var hasAuthorizeAttribute = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType&lt;Microsoft.AspNetCore.Authorization.AuthorizeAttribute&gt;().Any() || context.MethodInfo.GetCustomAttributes(true).OfType&lt;Microsoft.AspNetCore.Authorization.AuthorizeAttribute&gt;().Any(); (3认同)
  • 它可以工作,但是我必须在5.0.0-rc2中将参数设为可选(Required = false)-否则我无法尝试(看起来像是swashbucjke错误)。 (2认同)

小智 11

我稍微改进了尊敬的 Wille Esteche 的回答。如果您不想将标头应用于所有方法,而只想应用于您选择的控制器方法,则可以使用属性。

    [HttpPost]
    [Route(nameof(Auth))]
    [SwaggerHeader(Constants.HeaderDomainSid, "Encrypted User.Sid got from client", "abc123", true)]
    public ActionResult<string> Auth([FromHeader(Name = Constants.HeaderDomainSid)] string headerDomainSid = null)
    { .....
    
Run Code Online (Sandbox Code Playgroud)

属性类:

public class SwaggerHeaderAttribute : Attribute
{
    public string HeaderName { get; }
    public string Description { get; }
    public string DefaultValue { get; }
    public bool IsRequired { get; }

    public SwaggerHeaderAttribute(string headerName, string description = null, string defaultValue = null, bool isRequired = false)
    {
        HeaderName = headerName;
        Description = description;
        DefaultValue = defaultValue;
        IsRequired = isRequired;
    }
}
Run Code Online (Sandbox Code Playgroud)

筛选:

public class SwaggerHeaderFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        operation.Parameters ??= new List<OpenApiParameter>();

        if (context.MethodInfo.GetCustomAttribute(typeof(SwaggerHeaderAttribute)) is SwaggerHeaderAttribute attribute)
        {
            var existingParam = operation.Parameters.FirstOrDefault(p =>
                p.In == ParameterLocation.Header && p.Name == attribute.HeaderName);
            if (existingParam != null) // remove description from [FromHeader] argument attribute
            {
                operation.Parameters.Remove(existingParam);
            }

            operation.Parameters.Add(new OpenApiParameter
            {
                Name = attribute.HeaderName,
                In = ParameterLocation.Header,
                Description = attribute.Description,
                Required = attribute.IsRequired,
                Schema = string.IsNullOrEmpty(attribute.DefaultValue)
                    ? null
                    : new OpenApiSchema
                    {
                        Type = "String",
                        Default = new OpenApiString(attribute.DefaultValue)
                    }
            });
        }
    }
}
    
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 这个答案很适合我。我已经为控制器方法做了一些自定义属性,这些属性将读取额外的请求参数,并且通过这种方法,我可以在 swagger 中记录这些“隐藏”参数。我的想法是实现一个接口,其中包含获取标头名称、描述、isrequired 和默认值的方法。 (2认同)

小智 11

就我而言(.NET 5),我必须更改一些:

using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

public class AddRequiredHeaderParameter : IOperationFilter
{
     public void Apply(OpenApiOperation operation, OperationFilterContext context)
     {
         if (operation.Parameters == null)
             operation.Parameters = new List<OpenApiParameter>();

         operation.Parameters.Add(new OpenApiParameter()
         {
             Name = "userNr",
             In = ParameterLocation.Header,
             Required = true
         });

         operation.Parameters.Add(new OpenApiParameter()
         {
             Name = "periodNo",
             In = ParameterLocation.Header,
             Required = true
         });
     }
 }
Run Code Online (Sandbox Code Playgroud)

并Startup.cs --> ConfigureServices --> AddSwaggerGen 添加

c.OperationFilter<AddRequiredHeaderParameter>();
Run Code Online (Sandbox Code Playgroud)


Pav*_*kov 8

添加自定义标头的另一种方法是将参数添加到控制器操作中。
以下示例将向x-testUI 添加参数:

[HttpPost]
public IActionResult Test([FromHeader(Name="x-test")][Required] string requiredHeader)
{
    return Ok();
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 简要说明一下,[FromFromer]属性仅适用于使用ASP.Net Core而不是完整.Net的WebAPI实例。 (3认同)

小智 7

对于 Asp .Net MVC 5,您可以使用。
以下需要在 Swagger Config 文件中完成。

private class AddAuthorizationHeaderParameter: IOperationFilter   // as a nested class in script config file.
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
        {
            name = "Authorization",
            @in = "header",
            type = "string",
            required = true
        });
    }
}

c.OperationFilter<AddAuthorizationHeaderParameter>(); // finally add this line in .EnableSwagger
Run Code Online (Sandbox Code Playgroud)

您还可以为 Swagger 中的标头实现添加任何标头。