我正在尝试使用 Json.NET 在 vb.NET 中序列化对象。
对象无法正确序列化。 这似乎是因为类上的某些属性。下面是类定义 - 一个非常简单的定义。
下面是要序列化的代码:
Dim MyObject As New TestClass() With {.Property1 = "Hello", .Property2 = 3}
Dim Serialized As String = JsonConvert.SerializeObject(MyObject)
执行上述 2 行后,变量 Serialized 具有以下值(这不是我期望或想要的(:
"Namespace1.TestClass"
当我完全删除类属性(仅删除类属性,而不是属性属性(然后执行相同的 2 行代码时,变量 Serialized 具有以下值(这是我所期望的(:
{"Property1":"Hello","Property2":"3"}
这只是一个例子:我们有许多具有这些属性的此类类。 我们需要用 Json.NET 对它们进行序列化。删除属性是不可能的,我正在处理的类是现有应用程序和基于 WCF 的 Web 服务系统的一部分(即我们系统的.part需要保持我们当前的 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
问题是你的类TypeConverterAttribute
。 当 Json.Net 看到这一点时,它将使用关联的TypeConverter
将对象转换为字符串。 在这种情况下,它会导致输出类的类型名称。
可以通过向应用了TypeConverterAttribute
的类添加JsonObjectAttribute
来覆盖不需要的行为。 但是,由于您的类似乎是生成的代码,因此除非可以修改代码生成器,否则逐个类执行此操作可能不可行。 在这种情况下,另一种替代方法是使用自定义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)
小提琴:https://dotnetfiddle.net/s6Ebmc
我想你不想改变你的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