C#使用DataContractJsonSerializer反序列化JSON始终得到空对象
解决DataContractJsonSerializer反序列化JSON得到空对象的问题
我一眼就看出问题出在JSON属性名和C#类字段的大小写不匹配,还有DataMember的配置上。咱们一步步来拆解和修复:
问题根源
你调用Web服务返回的JSON里,所有属性都是大写开头(比如Id、GroupId、Name),但你的Credential类里的字段却是小写开头(id、groupid、name)。DataContractJsonSerializer默认是大小写敏感的,而且默认会用字段的名称去匹配JSON里的键,两者完全不匹配,自然填充不了值;又因为这个序列化器不会因为找不到匹配字段而抛出异常,所以你就得到了全空的对象。
修复方案
你需要给每个[DataMember]特性指定Name参数,对应JSON里的键名,同时建议把公共字段改成属性(这是C#的规范写法,也更符合序列化器的预期):
修改后的Credential类
[Serializable, DataContract(Name = "Credential")] public class Credential { [DataMember(Name = "Id")] public Guid Id { get; set; } = Guid.Empty; [DataMember(Name = "GroupId")] public Guid GroupId { get; set; } = Guid.Empty; [DataMember(Name = "Name")] public string Name { get; set; } = string.Empty; }
额外优化点
- 去掉
XmlRoot("Credential"):你用的是JSON序列化器,这个XML相关的特性完全没用,属于多余配置。 - 用
using语句管理MemoryStream:自动释放资源比手动调用Close()更安全可靠,修改后的反序列化代码如下:
var serF = new DataContractJsonSerializer(typeof(Credential)); using var msF = new MemoryStream(Encoding.UTF8.GetBytes(response2.Content)); var cred1 = serF.ReadObject(msF) as Credential;
如果后续需要匹配JSON里更多的属性(比如Username、Notes),只需要给类里新增对应属性,并加上[DataMember(Name = "对应JSON键名")]特性即可。
内容的提问来源于stack exchange,提问作者Oliver M.
相关产品推荐
相关产品推荐

