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

C# 带Body的GET请求硬编码JSON正常但序列化对象失效问题

问题原因

  • 首先GET请求携带请求体本身属于不符合HTTP规范的hack实现,你通过反射修改ContentBodyNotAllowed内部字段的逻辑本身稳定性极低,不同.NET版本的内部类结构、字段名可能存在差异,这是底层的隐患。
  • 序列化得到的JSON与硬编码JSON存在隐性差异:
    • 可先打印两个场景下传入CallHttpGet的JSON字符串做对比,Newtonsoft默认序列化可能会输出多余的空格、换行,或者如果实体类新增了未加[JsonIgnore]的字段也会被一同序列化,导致服务端解析JSON失败。
    • 另一个高频触发原因:你当前代码中使用的StreamWriter默认是带BOM(字节顺序标记)的UTF-8编码,硬编码的JSON本身不带BOM,部分严格的服务端会把BOM识别为无效字符,直接抛出JSON格式错误。
  • 缺少显式的Content-Length请求头:硬编码的JSON长度固定,HttpWebRequest可能自动计算了请求体长度,而序列化后的动态JSON没有显式设置长度,部分服务端会因为无法确定请求体大小直接拒收请求。

解决方案

最优方案(根治问题)

将GET请求改为POST请求即可,GET请求带请求体的行为本身就不被绝大多数反向代理、CDN、服务端框架默认支持,修改request.Method = "POST",不需要再做反射修改内部字段的hack操作,兼容性最好。

兼容方案(必须保留带请求体的GET请求时使用)

  1. 校验序列化结果:在调用接口前打印序列化得到的JSON,和硬编码的JSON对比确保内容完全一致,可给实体类加[JsonObject(MemberSerialization.OptIn)]注解,只序列化标记了[JsonProperty]的字段,避免多余字段被序列化。
  2. 调整请求体写入逻辑,使用无BOM的UTF-8编码,同时显式设置Content-Length头:
public string CallHttpGet(string url, string json)
{
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";
    request.ContentType = "application/json";
    request.Headers.Add("Authorization",authorizationKey);
    request.Headers.Add("X-ng-requestTime", requestTime);
    
    var type = request.GetType();
    var currentMethod = type.GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request);
    var methodType = currentMethod.GetType();
    methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentMethod, false);

    // 显式计算请求体字节长度,设置Content-Length
    byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
    request.ContentLength = jsonBytes.Length;
    // 直接写入字节流,避免StreamWriter的BOM问题
    using (var stream = request.GetRequestStream())
    {
        stream.Write(jsonBytes, 0, jsonBytes.Length);
    }

    var response = (HttpWebResponse)request.GetResponse();
    return new StreamReader(response.GetResponseStream()).ReadToEnd();
}
  1. 序列化时关闭格式化输出,避免多余的空格换行:
var json = JsonConvert.SerializeObject(new MuaDesignationListRequest
{
    DesignationType = "MUAP"
}, new JsonSerializerSettings
{
    Formatting = Formatting.None
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:45:03