当前位置: 首页 > 知识库问答 >
问题:

Swagger UI不会在控制器的GET操作中为我的复杂类型参数呈现体参数字段

危璞
2023-03-14

我有一个ASP。NETWebAPI2项目,我在其中添加了Swagger-SwashBucklV5。6.0. 一切正常。Swagger UI按预期呈现我的API的测试endpoint。

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

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

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

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

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

共有2个答案

邵祺
2023-03-14

关于是否应该在GET请求中包含有效负载“Body content”的讨论层出不穷。正如你提到的,它是由HTTP支持的,但是你会在互联网上发现很多人建议不要这样做。我猜那个大摇大摆的团队也希望你不要使用它。

宋弘壮
2023-03-14

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

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

这是Swagger开发人员内部已知的问题,并在2016年进行了讨论,最终决定是swagger不支持HTTP GET方法中的请求体。这是已经关闭的问题的链接。

这里有三个选项:

  • 保持方法原样,并在Postman中测试它,而不是在Swagger中。
  • 按照下面的步骤来实现上面的图片,但是请注意,它只会修复用户界面部分,当你按下尝试时,控制器中总是会出现nullSearchModel它出来!昂首阔步。
  • 使其成为[HttpPost方法,而不是[Httpget]

如何使昂首阔步UI显示GET方法与请求体:

首先,创建一个属性类:

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}" }
        });
    }
}

最后,不要忘记在SwaggerConfig中注册IOperationFilter

c.OperationFilter<ModelInBodyOperationFilter>();

 类似资料:
  • 我目前正在尝试在Typo3 v10中获得一个扩展,它使用户能够显示、编辑、更新、禁用和启用其他用户帐户。 不幸的是,我遇到了一个问题,我不能使用禁用用户作为操作的参数: 这将导致以下错误:

  • Swagger不在UI和JSON中显示参数,即使我的方法有参数,当我添加[FromBody]标记 Swagger UI无参数JSON文件无参数 操作方法时,尤其会发生这种情况: 我使用全新的 Asp.net 核心3.1和2.2 Web应用程序与API模板来测试这一点,我完全按照文档配置 服务进行了配置: 配置:< br > 当我使用[FromRoute]等其他属性时,它确实起作用 我还尝试了这样的

  • 问题内容: 我在Controller内部有一个Action函数,该函数被AJAX调用。该操作采用1个参数。在客户端,我构造了一个JSON对象,该对象应序列化为该1参数。我遇到的问题是参数类被声明为抽象。因此,它不能被实例化。 当AJAX击中该动作时,我得到以下信息: 无法创建抽象类。 堆栈跟踪: [MissingMethodException:无法创建抽象类。] System.RuntimeTyp

  • 问题内容: ./chains.go:26:10:不能在作业中使用UpperCaseHandler(typefunc(asl.MessageDelivery))作为asl.MessageHandler类型./chains.go:37:86:无法使用RepeatHandler(类型func(asl.MessageDelivery))与Repeater.ConsumeFunc的参数中的asl.Messa

  • 问题总结:我想传递一个带有类型参数(如

  • 我有过 我通过这种方式传递profileJson: 但是我的配置文件Json对象具有所有空字段。我应该怎么做才能让Spring解析我的json?