You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发送JSON数据时遭遇400 Bad Request问题求助

问题描述

我尝试向API发送JSON数据,但无法成功送达:

  • 数据是对象列表,第一次发送空数组时成功
  • 第二次发送非空数组直接返回400状态码,调试器根本没进入控制器
  • 怀疑是JSON反序列化失败(返回application/problem+json类型响应),但也不排除其他可能
  • 已尝试的方案:使用[FromBody]特性、切换内置JSON序列化器/Newtonsoft序列化器、添加Formatting.Indented,均无效
  • 怀疑对象中存储物理目录路径的字符串参数导致问题,该参数包含/、\、空格及其他特殊字符

客户端代码

using (HttpClient client = new HttpClient())
{
    var message = new HttpRequestMessage();
    message.Content = JsonContent.Create(files, typeof(List<WatchedFile>));
    message.RequestUri = new Uri("http://localhost:5245/api/fileagent");
    message.Method = HttpMethod.Post;

    var response = await client.SendAsync(message);   
    
    if (!response.IsSuccessStatusCode)
    {
        logger.LogError($"Sending to api was not successful {(int)response.StatusCode}");
    }
}

注:这段代码待重构,计划改为注入HttpClient而非直接使用using语句

控制器代码

[HttpPost]
public async Task<ActionResult> AddMessages([FromBody]List<WatchedFile> messages)
{
    messages.ForEach(x => x.Ipaddress = HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString());
    //send to repository                   
    await context.WatchedFiles.AddRangeAsync(messages);
    await context.SaveChangesAsync();
    return Ok();
}

解决步骤
  1. 先获取详细错误信息
    400错误的application/problem+json响应包含具体错误细节,不要只打印状态码,把响应内容读出来:

    if (!response.IsSuccessStatusCode)
    {
        var errorContent = await response.Content.ReadAsStringAsync();
        logger.LogError($"API请求失败,状态码:{(int)response.StatusCode},错误详情:{errorContent}");
    }
    

    这一步能直接定位反序列化失败的具体字段,比如路径字符串的转义问题,或者WatchedFile类的属性与JSON字段不匹配。

  2. 检查WatchedFile类定义
    确保类的属性与序列化后的JSON字段完全匹配:

    • 所有需要序列化的属性是否为public?
    • 是否存在需要特殊处理的类型(如日期、枚举)?
    • 存储路径的属性是否标记了正确的序列化特性?比如用System.Text.Json时,是否需要[JsonPropertyName]匹配字段名?
  3. 验证路径字符串的序列化结果
    物理路径里的\在JSON中需转义为\\,正常序列化器会自动处理。可以先将files序列化为字符串打印,确认格式是否正确:

    var jsonStr = JsonSerializer.Serialize(files, new JsonSerializerOptions { WriteIndented = true });
    logger.LogInformation("待发送JSON:{JsonStr}", jsonStr);
    

    如果发现路径未正确转义或存在非法字符,可手动处理(如替换非法字符,或调整序列化器配置)。

  4. 替换JsonContent创建方式
    改用StringContent手动序列化,明确指定编码和媒体类型,排除JsonContent.Create的隐式配置问题:

    var jsonStr = JsonSerializer.Serialize(files);
    message.Content = new StringContent(jsonStr, Encoding.UTF8, "application/json");
    
  5. 检查控制器模型验证配置
    调试器未进入控制器,大概率是模型绑定失败。可在Program.cs中配置序列化器和模型验证:

    builder.Services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.AllowTrailingCommas = true;
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
        });
    

内容的提问来源于stack exchange,提问作者technologyresearcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 23:06:10