VS2012生成JSON类后JavaScriptSerializer反序列化属性未填充求助
问题分析与解决方案
你遇到的问题根源很明确:你的类属性名称和JSON字符串中的键名不匹配,导致JavaScriptSerializer无法正确映射数据。
先对比一下你的JSON结构和生成的类:
你的JSON里对应包裹信息的键是"APN":
{ "ParcelFound":true, "APN":{ "Book":"510", "Map":"11", "Item":"668", "clean":"51011668", "formatted":"510-11-668", "link":"\/api\/parcel\/51011668" } }
但你通过VS生成的Rootobject类里,对应的属性却是ParcelInfo:
Public Class Rootobject Public Property ParcelFound As Boolean Public Property ParcelInfo As New APN End Class
JavaScriptSerializer默认是严格按照名称匹配来映射数据的,它找不到ParcelInfo对应的JSON键,自然就会保留属性的默认空对象,导致MCD.ParcelInfo.formatted为Nothing。
两种解决方法:
方法1:直接修改类属性名,和JSON键名完全匹配
这是最简单直接的方式,把ParcelInfo改成APN即可:
Public Class clsMCParcelData Public Class Rootobject Public Property ParcelFound As Boolean Public Property APN As New APN ' 此处改为和JSON键一致的APN End Class Public Class APN Public Property Book As String Public Property Map As String Public Property Item As String Public Property clean As String Public Property formatted As String Public Property link As String End Class END CLASS
修改后,你的反序列化代码不需要改动,直接通过MCD.APN.formatted就能拿到510-11-668了。
方法2:用DataMember特性做名称映射(保留原属性名)
如果代码里已经有很多地方用到了ParcelInfo,不想修改属性名,可以通过特性指定JSON键和属性的映射关系。需要先引用System.Runtime.Serialization程序集,再修改类:
Imports System.Runtime.Serialization Public Class clsMCParcelData <DataContract> Public Class Rootobject <DataMember(Name:="ParcelFound")> Public Property ParcelFound As Boolean <DataMember(Name:="APN")> ' 明确指定JSON键为APN,对应当前属性 Public Property ParcelInfo As New APN End Class <DataContract> Public Class APN <DataMember(Name:="Book")> Public Property Book As String <DataMember(Name:="Map")> Public Property Map As String <DataMember(Name:="Item")> Public Property Item As String <DataMember(Name:="clean")> Public Property clean As String <DataMember(Name:="formatted")> Public Property formatted As String <DataMember(Name:="link")> Public Property link As String End Class END CLASS
注意:使用这个方法时,需要给所有需要映射的属性加上DataMember特性,同时类要加上DataContract特性,这样序列化器才能识别映射规则。
验证效果
不管用哪种方法,修改后运行你的反序列化代码:
Dim jss As New JavaScriptSerializer, MCD As New clsMCParcelData.Rootobject MCD = jss.Deserialize(Of clsMCParcelData.Rootobject)(raw)
现在MCD.ParcelInfo.formatted(方法2)或者MCD.APN.formatted(方法1)就能正确返回510-11-668了。
内容的提问来源于stack exchange,提问作者RobWaibel
相关产品推荐
相关产品推荐

