我有一个 ASP.NET Web API 2 项目,我在其中添加了 Swagger - Swashbuckle v5.6.0。一切正常。Swagger UI 按预期呈现我的 API 的测试端点。
我在我的 API 中添加了一个新的控制器。有一个GET
带有复杂类型参数的操作。对于复杂类型,Web API 尝试从消息正文中读取值。这是默认行为。
这是我的 GET 操作:
[HttpGet]
[Route("search")]
[ResponseType(typeof(List<SearchModel>))]
public IHttpActionResult Search(SearchModel searchOptions)
{
//....
return Ok();
}
她是我的复杂类型:
public class SearchModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
public string AddressLine1 { get; set; }
public string City { get; set; }
public string Telephone { get; set; }
public string MobilePhone { get; set; }
}
问题:
但是 Swagger UI 不会在GET
操作中为我的复杂类型呈现 body 参数字段。ForPOST
和PUT
actions Swagger UI 按预期呈现 body 参数字段,但不适用于我的GET
操作中的复杂类型。
从截图中可以看出,Swagger UI 为我的复杂类型中的属性呈现查询参数字段,而不是像在POST
and的情况下那样为我的类型呈现主体参数字段PUT
。
GET
从 Postman 进行测试并在请求正文中填充 json 时,我的操作运行良好。通过在 Visual Studio 中的操作中设置断点,我可以看到值绑定到我的操作参数中的对象。
I have tried to decorate the parameter in my action with [FromBody]
(which is the default for complex type) but same result.
Is this a bug in Swagger? Or am I missing something?
Sadly, you can't do what you want with Swagger. You can't send a request model in an HTTP GET method. You can however change the swagger UI to look like this:
but you won't be able to receive the model in your controller.
This is a known issue within the Swagger developers and it was discussed in 2016 and the final decision is that swagger won't support a request body in an HTTP GET method. Here is the link to the already closed issue.
You have three options here:
null
SearchModel
当您按下Try it out!
swagger时,您将始终在控制器中结束。[HttpPost
方法而不是[HttpGet]
.如何使 swagger UI 显示带有请求正文的 GET 方法:
首先,创建一个Attribute
类:
public class ModelInBodyAttribute : Attribute
{
public ModelInBodyAttribute(string modelName, string description, bool isRequired)
{
this.ModelName = modelName;
this.Description = description;
this.IsRequired = IsRequired;
}
public string ModelName { get; set; }
public bool IsRequired { get; set; }
public string Description { get; set; }
}
然后你可以在控制器中装饰你的方法:
[ModelInBody(modelName: nameof(SearchModel), description: "My model description", isRequired: true)]
[HttpGet]
[Route("search")]
[ResponseType(typeof(List<SearchModel>))]
public IHttpActionResult Search(SearchModel searchOptions)
{
//....
return Ok(new List<SearchModel>());
}
之后创建IOperationFilter
类(ModelInBodyOperationFilter
):
public class ModelInBodyOperationFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var attribute = apiDescription.GetControllerAndActionAttributes<ModelInBodyAttribute>().FirstOrDefault();
if (attribute == null)
{
return;
}
operation.parameters.Clear();
operation.parameters.Add(new Parameter
{
name = attribute.ModelName,
description = attribute.Description,
@in = "body",
required = attribute.IsRequired,
schema = new Schema { @ref = $"#/definitions/{attribute.ModelName}" }
});
}
}
最后,不要忘记注册IOperationFilter
in SwaggerConfig
:
c.OperationFilter<ModelInBodyOperationFilter>();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句