使用自定义模型活页夹时 Swashbuckle 请求参数不起作用

Swashbuckle request parameters not working when using custom model binder

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

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

DTO 有一个 Guid 属性:

public class GetSingleRequest
{
  public Guid Id { get; set; }
}

我已经配置了一个自定义模型联编程序以将 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

我试过使用 MapTypeISchemaFilter 如下:

// startup.cs
c.MapType<Guid>(() => new OpenApiSchema {Type = "string", Format = null});
// 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;
    }
  }

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

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

How can I configure Swagger to pass a string instead of a Guid as part of the URI when I have a custom model binder configured?

其实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();
            }); 

或者你把路由模板中的id改成Id.

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

            return Ok();
        }

测试结果如下: