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

本地正常UAT异常:NewtonSoft JsonConvert.DeserializeObject报错

解决Newtonsoft.Json反序列化时的System.Reflection.DefaultMemberAttribute异常

问题背景

你遇到的情况确实有点棘手:本地Win10 IIS部署时代码运行完全正常,但到UAT服务器上就出问题了,反序列化JSON的时候抛出了和System.Reflection.DefaultMemberAttribute相关的异常。先把你提供的关键信息理清楚:

要反序列化的JSON内容:

{ "header": { "application-code": "ZZZ" }, "piece": [ "0000001" ] }

对应的实体类定义:

public class RequestPiece { 
    [JsonProperty(PropertyName = "header")] 
    public RequestHeaderPiece requestheader { get; set; } 
} 

public class ResponseHeaderPiece { 
    [JsonProperty(PropertyName = "application-code")] 
    public string application_code { get; set; } 
} 

public class ResponsePiece { 
    [JsonProperty(PropertyName = "header")] 
    public ResponseHeaderPiece responseheader { get; set; } 
    [JsonProperty(PropertyName = "piece")] 
    public List<string> piece { get; set; } 
}

触发异常的核心代码段:

public List<string> getP(string pieces) { 
    try{ 
        restAPI.Url = config.PieceServiceUrl + "/" + pieces; 
        restAPI.Method = "GET"; 
        restAPI.ClientId = config.ClientId; 
        restAPI.Secret = config.SecretKey; 
        string returnString = restAPI.callJsonService(); 
        log.Info(System.Reflection.MethodInfo.GetCurrentMethod() + "::JSON response => " + returnString); 
        ResponsePiece rp = JsonConvert.DeserializeObject<ResponsePiece>(returnString); 
        log.Info(System.Reflection.MethodInfo.GetCurrentMethod() + "::JSON response " + rp.piece); 
        return rp.piece; 
    } catch (Exception ex) { 
        log.Error(System.Reflection.MethodInfo.GetCurrentMethod() + "::failed::" + ex.Message.ToString() + " => " + ex.StackTrace.ToString()); 
        return null; 
    } 
}

异常堆栈的关键报错信息:

System.Reflection.DefaultMemberAttribute.m_memberName => 
at System.Reflection.RtFieldInfo.PerformVisibilityCheckOnField(IntPtr field, Object target, IntPtr declaringType, FieldAttributes attr, UInt32 invocationFlags) 
at System.Reflection.RtFieldInfo.InternalGetValue(Object obj, Boolean doVisibilityCheck, Boolean doCheckConsistency) 
at System.Reflection.RtFieldInfo.GetValue(Object obj) 
at System.Attribute.GetHashCode() 
...
at Newtonsoft.Json.Serialization.DefaultContractResolver.InitializeContract(JsonContract contract)

问题根源分析

这个异常本质是反射访问权限的差异问题:本地Win10的IIS通常运行在权限较高的上下文(比如你的个人用户账户),而UAT服务器的应用池一般用更受限的身份(比如ApplicationPoolIdentity)。旧版本的Newtonsoft.Json在解析契约时,会直接反射访问DefaultMemberAttribute的私有字段m_memberName,在权限受限的环境下这种操作会被拦截,进而抛出异常。

解决方案(按优先级推荐)

1. 升级Newtonsoft.Json到最新稳定版

这是最彻底的解决方式——这个问题是Json.NET旧版本的已知bug,新版本已经修复了这个反射权限问题,改用了更安全的方式获取属性信息,不再直接访问私有字段。

  • 打开项目的NuGet包管理器,找到Newtonsoft.Json,升级到最新的稳定版本(比如13.x及以上)
  • 重新编译部署到UAT服务器测试

2. 临时调整应用池权限(不推荐,仅应急使用)

如果因为项目限制无法升级Json.NET,可以临时调整UAT服务器的应用池权限:

  • 打开IIS管理器,找到你的应用对应的应用池
  • 右键选择「高级设置」,将「标识」从ApplicationPoolIdentity改为LocalSystem或其他具有更高权限的账户
  • 注意:这种方式会降低服务器的安全性,只适合紧急排查时临时使用

3. 自定义契约解析器(备选方案)

如果升级后仍有问题,可以自定义一个契约解析器,跳过可能引发异常的反射检查:

public class SafeContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type objectType)
    {
        try
        {
            return base.CreateContract(objectType);
        }
        catch (ReflectionTypeLoadException)
        {
            // 忽略反射加载异常,返回默认基元契约
            return base.CreatePrimitiveContract(objectType);
        }
        catch (Exception)
        {
            // 捕获其他反射相关异常,降级处理
            return base.CreateContract(objectType);
        }
    }
}

然后在反序列化时指定使用这个解析器:

var jsonSettings = new JsonSerializerSettings
{
    ContractResolver = new SafeContractResolver()
};
ResponsePiece rp = JsonConvert.DeserializeObject<ResponsePiece>(returnString, jsonSettings);

验证步骤

  1. 优先尝试升级Json.NET,这是最稳妥的解决路径
  2. 升级后重新部署到UAT,测试接口是否正常工作
  3. 若升级不可行,再尝试调整应用池权限或自定义解析器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:08:49