【问题标题】:.NET Core Web API posting formdata and getting 400 error.NET Core Web API 发布表单数据并收到 400 错误
【发布时间】:2022-01-10 07:08:45
【问题描述】:

我认为问题出在空值上。我已经测试了包含诸如

之类的值的有效载荷
{
 name: 'My Name', 
 householdSize: '3'
}

服务器会收到请求。但是,我仍然希望允许用户不输入任何数据,但是,当这种情况发生时,服务器永远不会被命中(我有一个断点要测试)。

我正在使用带有 .NET Core Web API 的 js 前端。

我有一个看起来像这样的有效载荷

{
 name: null, 
 householdSize: null
}

我的视图模型是这样的

public class MyViewModel
{
    [Required]
    public string Name { get; set; }

    [Required]
    public EHouseholdSize HouseholdSize { get; set; }

    public enum EHouseholdSize
    {
        One = 1,
        Two,
        Three,
        Four,
        FivePlus
    }
}

我的控制器就是这样

public async Task<IActionResult> Add([FromBody]QuestionnaireViewModel viewModel)
{
    if(!ModelState.IsValid)
    {
        return BadRequest();
    }

    // Do stuff        

    return Ok();
}

【问题讨论】:

    标签: c# .net-core asp.net-core-webapi


    【解决方案1】:

    您的ModelState 在发送null 值时无效,因为您的视图模型的两个属性都具有[Required] 属性。发送{"name": null, "houseHoldSize": null} 等价于`` 或{}。 因此,不满足要求并使模型状态无效。这就是为什么它永远不会通过你的 if 块。

    因此,如果您想允许发布 null 或空值,则需要从 ViewModel 属性中删除 [Required] 属性。

    【讨论】:

    • 我明白了。但是,假设我发布了无效数据。例如,假设我发布了一个值为 7 的枚举,该枚举不存在并且是一个无效参数。服务器还会收到请求吗?不,实际上 400 甚至不是来自 API。请求本身甚至根本没有命中 API。
    • 我想会的。除非你为此指定Data Annotations
    • 你怎么看?如果请求没有命中 API,那么谁发送 400 响应?正如其他答案中提到的,[ApiController] 属性可以自动完成一些工作。
    【解决方案2】:

    当您使用 API 控制器(具有 [ApiController] 属性)时,将自动验证操作参数,并且您不需要 if ( !ModelState.IsValid ),因为如果模型状态无效,它将永远不会被命中。 Api 控制器将在它之前返回 BadRequest。因此,从您的 ViewModel 属性中删除 [Required] 属性或使其不为空

    另一件事是如果您的项目启用了可为空(主要是 6 个项目)

      <Nullable>enable</Nullable> 
    

    您还需要将属性名称设为可空

     public string? Name { get; set; }
    

    否则你会得到一个 BadRequest “The Name field is required.”,即使你删除了 [Required] 属性。

    【讨论】:

    • 那么我可以假设控制器操作的 400 错误意味着我的有效负载中的某些内容不正确吗?
    • @SomeDev ,是的,您的输入参数无效,但控制器始终运行自动验证检查。
    • 那么好的前端,如果我的响应是 400,我想我会假设表单数据不正确。谢谢。
    • @SomeDev ,这与表单数据无关,您使用 ajax 发送的模型根据您的数据属性无效
    • @SomeDev 是的,你是对的。但是我看到您发布了出色的答案,您关闭了对所有控制器的所有操作的验证。我不认为这是一个好主意。您只需从不需要的属性中删除所需的属性,而不是关闭任何验证。
    猜你喜欢
    • 2018-02-21
    • 2017-08-05
    • 1970-01-01
    • 2018-03-12
    • 2019-08-14
    • 2020-12-04
    • 2017-08-09
    • 2020-08-14
    • 2018-12-28
    相关资源
    最近更新 更多