我正在尝试使用Json.NET在vb.NET中序列化对象。
对象无法正确序列化。这似乎是因为该类的一些属性。 下面是类定义 - 一个非常简单的定义。
以下是序列化的代码:
Dim MyObject As New TestClass() With {.Property1 = "Hello", .Property2 = 3}
Dim Serialized As String = JsonConvert.SerializeObject(MyObject)
在执行上述两行之后,变量序列化具有以下值(这不是我期望或想要的):
"Namespace1.TestClass"
当我完全删除类属性(只是类属性,而不是属性属性)然后执行相同的2行代码时,变量序列化具有以下值(这就是我期待):
{"Property1":"Hello","Property2":"3"}
这只是一个例子:我们有许多具有这些属性的类。我们需要使用Json.NET对它们进行序列化。 删除属性是不可能的,我正在处理的类是现有应用程序和基于WCF的Web服务系统的一部分(即我们系统的一部分需要我们当前的WCF序列化系统保持到位,以及我们系统需要的另一部分用Json序列化同一个类..我不会进入"为什么"细节,只是我们为数据库写入序列化了数千个这样的对象,并且具有速度和空间位置)。
我也意识到我可以使用JsonTextWriter进行序列化,但是我们遇到了维护问题 - 每次添加/删除属性时我们都要记住要正确维护序列化代码。
那么如何在不删除属性的情况下正确序列化此类?
我没有在NewtonSoft网站上看到任何内容,也没有在其他任何地方看到过这个问题。
这里再次是类定义以及属性。
<System.CodeDom.Compiler.GeneratedCodeAttribute ("System.Xml", "2.0.50727.3053"), _
System.SerializableAttribute(), _
System.Diagnostics.DebuggerStepThroughAttribute(), _
System.ComponentModel.DesignerCategoryAttribute("code"), _
System.Xml.Serialization.XmlTypeAttribute ([Namespace]:="http://Namespace.com/SomePath/SomeXsd.xsd", TypeName:="TestClass"), _
System.ComponentModel.TypeConverterAttribute(GetType (System.ComponentModel.ExpandableObjectConverter))> _
Partial Public Class TestClass
Private _Property1 As String
Private _Property2 As Integer
<System.ComponentModel.Browsable(False), System.Xml.Serialization.XmlIgnoreAttribute()> _
Public Property Property1() As String
Get
Return Me._Property1
End Get
Set(ByVal value As String)
If (Me._Property1 <> value) Then
Me._Property1 = value
End If
End Set
End Property
<System.ComponentModel.Browsable(False), System.Xml.Serialization.XmlIgnoreAttribute()> _
Public Property Property2() As String
Get
Return Me._Property2
End Get
Set(ByVal value As String)
If (Me._Property2 <> value) Then
Me._Property2 = value
End If
End Set
End Property
End Class
答案 0 :(得分:1)
问题在于您班级的TypeConverterAttribute
。当Json.Net看到它时,它将使用关联的TypeConverter
将对象转换为字符串。在这种情况下,它会导致输出类的类型名称。
您可以通过向已应用JsonObjectAttribute
的类添加TypeConverterAttribute
来覆盖不需要的行为。但是,由于您的类似乎是生成代码,因此除非您可以修改代码生成器,否则在逐个类的基础上执行此操作可能是不可行的。在这种情况下,另一种方法是使用自定义IContractResolver
来强制Json.Net忽略具有它的类的TypeConverter
。
以下是解析器所需的代码:
Class TypeConverterIgnoringResolver
Inherits DefaultContractResolver
Protected Overrides Function CreateContract(objectType As Type) As JsonContract
If objectType.GetCustomAttributes(True) _
.OfType(Of System.ComponentModel.TypeConverterAttribute)() _
.Any() _
Then
Return MyBase.CreateObjectContract(objectType)
End If
Return MyBase.CreateContract(objectType)
End Function
End Class
你可以像这样使用解析器:
Dim MyObject As New TestClass() With {.Property1 = "Hello", .Property2 = 3}
Dim Settings As New JsonSerializerSettings
Settings.ContractResolver = New TypeConverterIgnoringResolver()
Dim Serialized As String = JsonConvert.SerializeObject(MyObject, Settings)
Console.WriteLine(Serialized)
答案 1 :(得分:0)
我想你不想改变你的TestClass
,因为它必须是由某个工具生成的,我建议从中派生一个新类:
Imports Newtonsoft.Json
<JsonObject()>
Public Class OtherClass
Inherits TestClass
End Class
并使用属性<JsonObject()>
。这应该可以解决问题:
Dim MyObject As New OtherClass() With {.Property1 = "Hello", .Property2 = 3}
Dim Serialized As String = JsonConvert.SerializeObject(MyObject)
更新:
由于您已经在使用Partial,因此您可以扩展它以创建一个新的(在另一个文件夹中):
Imports Newtonsoft.Json
<JsonObject()>
Partial Public Class TestClass
End Class