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

C# API Post接收JSON:本地正常远程FromBody为null问题排查

解决ASP.NET Web API接收非标准多行JSON(application/json类型)的问题

我一眼就看出问题出在哪了——当请求Content-Type切换成application/json时,ASP.NET Web API的默认模型绑定逻辑和text/plain完全不一样,直接导致你的_inputJson变成了null,触发了204的返回。

问题根源拆解

  • 用text/plain时,Web API会把请求体的原始内容直接塞给[FromBody] string,所以你的processJson按换行拆分的逻辑能正常工作。
  • 但换成application/json后,Web API会自动尝试把请求体解析成标准JSON对象,而你的输入是每行一个独立JSON、没有数组包裹的非标准格式,解析直接失败,_inputJson就成了null,刚好命中你判断null返回204的分支。

解决方案

这里给你几个可行的处理方案,按需选择:

方案1:直接读取请求流的原始内容(最稳妥)

放弃依赖[FromBody] string的模型绑定,直接从请求流里读取完整的原始字符串,不管Content-Type是什么都能拿到正确内容。修改你的Post方法:

public async Task<HttpResponseMessage> PostString() {
    string _inputJson;
    // 直接读取请求流的原始内容
    using (var reader = new StreamReader(await Request.Content.ReadAsStreamAsync())) {
        _inputJson = await reader.ReadToEndAsync();
    }

    if (string.IsNullOrEmpty(_inputJson)) {
        return Request.CreateErrorResponse(HttpStatusCode.NoContent, "The Json was null");
    } else {
        try {
            var arrJson = processJson(_inputJson);
            using (ModelEntities entities = new ModelEntities()) {
                for (int i = 0; i < arrJson.Count; i++) {
                    var jTest = JsonConvert.DeserializeObject<TestClass>(arrJson[i].ToString());
                    var userRoles = jTest.RolesClass;
                    var userId = jTest.Id;
                    entities.User.Add(jTest);
                    
                    foreach (var _role in userRoles) {
                        if (_role != null) {
                            _role.id = userId;
                            entities.userRoles.Add(_role);
                        }
                    }
                }
                // 建议统一保存,不要循环里多次Save,性能会差很多
                entities.SaveChanges();
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        } catch (Exception ex) {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message.ToString());
        }
    }
}

方案2:优化processJson的拆分逻辑

你的拆分只处理了\n,但实际请求里可能存在Windows风格的\r\n或者空行,会导致拆分出无效的空字符串,后续反序列化报错。优化一下方法:

public List<string> processJson(string strInput) {
    // 同时处理两种换行符,过滤掉空行
    return strInput.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries)
                   .Where(line => !string.IsNullOrWhiteSpace(line))
                   .ToList();
}

方案3:让发送方改成标准JSON数组(最优解)

如果远程服务器可以调整,建议让对方把请求体改成标准的JSON数组格式:

[
    {"id": "1","name": "Cindy","role": [{"name": "HR"}]},
    {"id": "2","name": "Frank","role": [{"name": "Admin"}]},
    {"id": "3","name": "John","role": [{"name": "Admin"},{"name": "HR"}]}
]

这样你可以直接用[FromBody] List<TestClass> _inputList接收,不需要自己拆分和反序列化,代码会简洁很多,也符合JSON规范。

额外建议

  • 尽量不要在循环里频繁调用SaveChanges(),这会多次触发数据库操作,严重影响性能,统一在循环结束后保存一次就好。
  • 可以加个日志记录,比如读取到_inputJson后把内容打出来,方便后续排查类似问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:48:27