C# MVC获取已注册用户数据做支付时报空引用异常问题
空引用问题排查定位
问题本质
触发System.NullReferenceException报错的核心原因,是反序列化得到的person实例本身不携带有效的address对象,和后续读取State字段的代码逻辑无关——如果address对象存在,根本不会触发导航属性get方法返回null的报错。
具体排查方向
- 核查Session写入person数据的查询逻辑
当前Session存取逻辑依赖person实体的序列化/反序列化实现,因为业务库拆分了人员表、地址表两个独立结构,如果当初往Session写入person数据时,使用ORM查询人员信息没有显式关联加载地址导航属性(比如EF查询遗漏了.Include(x => x.address)),查询得到的person实例的address属性默认就是null。此时将这个实例序列化后存入Session,得到的JSON字符串里根本没有address对应的字段内容,反序列化回来自然会把address属性置为null。
这也能解释为什么cliente.Name可以正常取值——Name是人员表本身的字段,不依赖关联表查询就能拿到。 - 核查序列化/反序列化的字段过滤规则
如果写入Session时已经正常带出了address数据,需要进一步检查序列化配置:- 是否给
person类的address属性加了[JsonIgnore]特性,导致序列化时直接跳过该字段 - 序列化配置是否开启了
NullValueHandling.Ignore,把识别为无需持久化的address字段直接过滤掉
以上两种情况都会导致存入Session的JSON缺失address内容,反序列化时自然拿不到对应对象。
- 是否给
- 排查Session缓存的历史无效数据
如果是后期才给person实体新增了address关联属性,那之前老版本代码写入Session的person JSON是没有address字段结构的。现在反序列化读取这类老Session值时,因为JSON结构和当前实体定义不匹配,address属性会保持默认的null值。
快速验证手段
在GetPerson方法拿到反序列化结果的位置打断点:
- 直接查看返回的person实例的
address属性是否为null - 把从Session读取到的原始
personJSONString复制出来做格式化,检查字符串内是否存在address对应的字段节点
对比原始JSON的结构,可以立刻定位是存值时缺失了address数据,还是反序列化的映射逻辑存在问题。
修复建议
- 调整Session存值的查询逻辑,写入person对象时必须显式关联加载address导航属性,确认序列化前person的address属性有实际值后再存入Session
- 移除address属性上不必要的
[JsonIgnore]标签,调整序列化配置确保address字段可以被正常序列化、反序列化 - 用户地址信息发生变更时,同步更新Session中存储的person序列化内容,避免读取到无address数据的老缓存
- 读取
person.address.State前增加基础判空逻辑,避免偶发的缓存缺失直接触发程序崩溃
内容的提问来源于stack exchange,提问作者E. Biagi
相关产品推荐
相关产品推荐

