使用自定义模型绑定器时,Swashbuckle 请求参数不起作用

Chr*_*ord 1 c# swagger swagger-ui swashbuckle asp.net-core

我有一个 ASP.NET Core 3.1 API 端点,配置如下:

[HttpGet("api/controller/action/{id}")]
public async Task<IActionResult> GetSingle([FromRoute] GetSingleRequest request) {...}
Run Code Online (Sandbox Code Playgroud)

DTO 有一个 Guid 属性:

public class GetSingleRequest
{
  public Guid Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我已经配置了一个自定义模型绑定器来将 Guid 属性绑定到字符串值,因为我使用的是短 guid 实现。使用 Postman 进行测试时一切正常。

但是,使用Swagger时,不是传递输入的路由参数,而是传递参数模板,例如

GET /api/controller/action/{id}     // Literally constructs the URI with {id}
GET /api/controller/action/abcd1234 // Not the value as entered
Run Code Online (Sandbox Code Playgroud)

我尝试过使用MapTypeandISchemaFilter如下:

// startup.cs
c.MapType<Guid>(() => new OpenApiSchema {Type = "string", Format = null});
Run Code Online (Sandbox Code Playgroud)
// startup.cs
c.SchemaFilter<GuidSchemaFilter>();

// GuidSchemaFilter.cs
internal class GuidSchemaFilter : ISchemaFilter
  {
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
      if (context.Type != typeof(Guid))
      {
        return;
      }

      schema.Type = "string";
      schema.Format = null;
    }
  }
Run Code Online (Sandbox Code Playgroud)

这些方法都没有改变这种奇怪的行为。

当我配置了自定义模型绑定程序时,如何配置 Swagger 以传递字符串而不是 Guid 作为 URI 的一部分?

Lou*_*raQ 6

当我配置了自定义模型绑定程序时,如何配置 Swagger 以传递字符串而不是 Guid 作为 URI 的一部分?

其实 c.MapType<Guid>(() => new OpenApiSchema {Type = "string", Format = null});这句话就足以解决问题了。

问题的关键是你的路由中的参数是Camel Case: id,而 GetSingleRequest 中的字段是Pascal Case: Id

作为注释,您可以添加c.DescribeAllParametersInCamelCase();使其忽略大小写问题。

  services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API" });
                c.MapType<Guid>(() => new OpenApiSchema { Type = "string", Format = null });
                c.DescribeAllParametersInCamelCase();
            }); 
Run Code Online (Sandbox Code Playgroud)

或者将路由模板中的 id 更改为 Id

        [HttpGet("api/controller/action/{Id}")]
        public async Task<IActionResult> GetSingle([FromRoute] GetSingleRequest request) 
        {

            return Ok();
        }
Run Code Online (Sandbox Code Playgroud)

这是测试结果:

在此输入图像描述