我应该如何使用JsonConvert序列化具有类属性的vb.NET对象?

时间:2015-10-05 15:34:54

标签: vb.net serialization json.net

我正在尝试使用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

2 个答案:

答案 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)

小提琴:https://dotnetfiddle.net/s6Ebmc

答案 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