如何允许引用类型参数的空请求体?

12

我正在构建一个 .Net Core api 控制器,我希望允许用户发送 GET 请求并且可以选择是否携带 MyRequest 类作为参数,因此如果使用 Get(null) 调用该方法将是正确的。

GET api/myModels 请求方法:

[HttpGet]
public ActionResult<IEnumerable<MyModel>> Get(MyRequest myRequest)
{
    if (myRequest == null)
        myRequest = new myRequest();

    var result = this._myService.Get(myRequest.Filters, myRequest.IncludeProperties);
    return Ok(result);     
}

MyRequest类:

public class MyRequest
{
    public IEnumerable<string> Filters { get; set; }
    public string IncludeProperties { get; set; }
}
当我使用Postman并在Body中留空时(例如用Get(null)的方式来调用空对象MyRequest),我会收到这样的Postman提示信息:

"需要非空请求体。"

但如果我使用Get方法并带上Body,它是起作用的。这里有一个类似的问题,但那里的参数是值类型。

this._myService.Get 方法里面有什么?你需要在 _myService.Get 方法内部处理空请求,或者创建一个没有 FiltersIncludeProperties 参数的 _myService.Get 方法重载。 - SᴇM
2个回答

27

这样做:

  services.AddControllersWithViews(options =>
  {
       options.AllowEmptyInputInBodyModelBinding = true;
  });

5
应该选择这个作为正确的解决方案。之前的答案不起作用。 - Zoran Stankovic
2
同样的东西可以在 services.AddControllers(this IServiceCollection services, Action<MvcOptions> configure) 中使用。 - Mauro Bilotti

4
你可以通过指定默认值为null并明确说明值将作为请求URL的一部分而使其成为可选参数。
[HttpGet]
public ActionResult<IEnumerable<MyModel>> Get([FromQuery]MyRequest myRequest = null)
{

顺便说一下,GET操作没有消息体,因此所有终端点参数都应通过查询字符串(或)作为路由值传递。

您应在API终端点中指定路由,并通过路由和查询字符串传递值。例如:

[HttpGet("{IncludeProperties}")]
//[Route("{IncludeProperties}")]
public ActionResult<IEnumerable<MyModel>> Get(string IncludeProperties = null, IEnumerable<string> Filters = null)
{

现在,有了上述内容,您可以请求您的API,如下所示:
GET api/myModels?Filters=

有一个 Get() 方法并设定默认参数值,和使用 Get(null) 两种调用方式之间有什么区别?结果都会出现 "A non-empty request body is required." 的错误提示,因为 OP 正在将请求 request 值传递给某个 this._myService.Get 方法,该方法可能会返回上述错误。 - SᴇM
1
@SᴇM,区别是什么?如果您想获取所有没有过滤器的数据(在这种情况下),该怎么办? - Rahul
@Rahul,我只是在说,调用Get(null)和使用默认参数的Get()是一样的。这并不能解决OP的问题。 - SᴇM
@ShaharShokrani 请查看答案中的编辑。如果有帮助,特别是最后一部分。 - Rahul
谢谢,它有效了,但请将答案编辑为[FromQuery] - Shahar Shokrani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接