Параметры запроса Swashbuckle не работают при использовании связующего элемента пользовательской модели

#c# #asp.net-core #swagger #swagger-ui #swashbuckle

#c# #asp.net-core #swagger #swagger-пользовательский интерфейс #swashbuckle

Вопрос:

У меня есть ASP.NET Конечная точка API Core 3.1 настроена следующим образом:

 [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
  

Я попытался использовать MapType и ISchemaFilter следующим образом:

 // 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, когда у меня настроен пользовательский связующий элемент модели?

Ответ №1:

Как я могу настроить 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();
            }); 
  

Или вы меняете идентификатор в шаблоне маршрута на Id.

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

            return Ok();
        }
  

Вот результат теста:

введите описание изображения здесь