Asp.net 大摇大摆的用户界面不';在控制器的GET操作中,为我的复杂类型参数呈现body参数字段

Asp.net 大摇大摆的用户界面不';在控制器的GET操作中,为我的复杂类型参数呈现body参数字段,asp.net,swagger,asp.net-web-api2,swagger-ui,swashbuckle,Asp.net,Swagger,Asp.net Web Api2,Swagger Ui,Swashbuckle,我有一个ASP.NETWebAPI2项目,其中添加了Swagger-SwashBucklV5.6.0。一切正常。Swagger UI按预期呈现我的API的测试端点 我在API中添加了一个新的控制器。有一个带有复杂类型参数的GET操作。对于复杂类型,Web API尝试从消息体读取值。这是默认行为 下面是我的GET操作: [HttpGet] [Route("search")] [ResponseType(typeof(List<SearchModel

我有一个ASP.NETWebAPI2项目,其中添加了Swagger-SwashBucklV5.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; }
}
问题:

    [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参数字段。对于
POST
PUT
操作,Swagger UI会按预期呈现body参数字段,但对于my
GET
操作中的复杂类型则不会

从屏幕截图中可以看出,Swagger UI为我的复杂类型中的属性呈现查询参数字段,而不是像在
POST
PUT
中那样为我的类型呈现主体参数字段

当从Postman测试并在请求体中填充json时,我的
GET
操作运行良好。通过在VisualStudio内部的操作中设置断点,我可以在操作参数中看到值绑定到我的对象

我试图用
[FromBody]
(这是复杂类型的默认值)来修饰操作中的参数,但结果相同


这是一只大摇大摆的虫子吗?还是我遗漏了什么?

遗憾的是,你不能自鸣得意地做你想做的事。无法在HTTP GET方法中发送请求模型。但是,您可以将招摇过市UI更改为如下所示:

但您将无法在控制器中接收模型

这是Swagger开发人员中的一个已知问题,在2016年讨论过,最终决定是Swagger不支持HTTP GET方法中的请求体

这里有三个选项:

  • 让方法保持原样,在《邮递员》中测试它,但不要大摇大摆
  • 按照以下步骤来实现上面的图片,但请注意,它只会修复UI部分,当您按
    尝试时,控制器中始终会出现
    null
    SearchModel
    大摇大摆
  • 将其设置为
    [HttpPost
    方法,而不是
    [HttpGet]

如何使用请求体使swagger UI显示GET方法:

首先,创建一个
属性
类:

公共类ModelInBodyAttribute:属性
{
公共ModelInBodyAttribute(字符串modelName、字符串描述、bool是必需的)
{
this.ModelName=ModelName;
这个。描述=描述;
this.IsRequired=IsRequired;
}
公共字符串ModelName{get;set;}
需要公共布尔值{get;set;}
公共字符串说明{get;set;}
}
然后,您可以在控制器中装饰您的方法:

[ModelInBody(modelName:nameof(SearchModel),description:“我的模型描述”,isRequired:true)]
[HttpGet]
[路线(“搜索”)]
[响应类型(类型(列表))]
公共IHttpActionResult搜索(搜索模型搜索选项)
{
//....
返回Ok(新列表());
}
然后创建
IOperationFilter
类(
ModelInBodyOperationFilter
):

公共类ModelInBodyOperationFilter:IOperationFilter
{
public void Apply(操作,SchemaRegistry SchemaRegistry,apisdescription apisdescription)
{
var attribute=apiscription.GetControllerAndActionAttributes().FirstOrDefault();
if(属性==null)
{
回来
}
operation.parameters.Clear();
操作.参数.添加(新参数
{
name=attribute.ModelName,
description=属性。description,
@in=“body”,
必需=attribute.IsRequired,
schema=newschema{@ref=$“#/definitions/{attribute.ModelName}”
});
}
}
最后,不要忘记在
SwaggerConfig
中注册
IOperationFilter

c.操作过滤器();

当您通过swagger发送请求时,您会注意到
Curl
部分是绝对正确的,但控制器中仍然没有任何内容。


遗憾的是,您无法使用Swagger实现您想要的功能。您无法在HTTP GET方法中发送请求模型。但是,您可以将Swagger UI更改为如下所示:

但您将无法在控制器中接收模型

这是Swagger开发人员中的一个已知问题,在2016年讨论过,最终决定是Swagger不支持HTTP GET方法中的请求体

这里有三个选项:

  • 让方法保持原样,在《邮递员》中测试它,但不要大摇大摆
  • 按照以下步骤实现上述图片,但请注意,它只会修复UI部分,当您在swagger中按
    尝试时,控制器中始终会出现
    null
    SearchModel
  • 将其设置为
    [HttpPost
    方法,而不是
    [HttpGet]

如何使用请求体使swagger UI显示GET方法:

首先,创建一个
属性
类:

公共类ModelInBodyAttribute:属性
{
公共ModelInBodyAttribute(字符串modelName、字符串描述、bool是必需的)
{
this.ModelName=ModelName;
这个。描述=描述;
this.IsRequired=IsRequired;
}
公共字符串ModelName{get;set;}
需要公共布尔值{get;set;}
公共字符串说明{get;set;}
}
然后,您可以在控制器中装饰您的方法:

[ModelInBody(modelName:nameof(SearchMod