【问题标题】:How should I serialize a vb.NET object which has class attributes with JsonConvert?我应该如何使用 JsonConvert 序列化具有类属性的 vb.NET 对象?
【发布时间】:2016-01-02 08:02:04
【问题描述】:

我正在尝试使用 Json.NET 序列化 vb.NET 中的对象。

对象无法正确序列化。这似乎是因为类的某些属性。 下面是类定义——一个非常简单的定义。

这是序列化的代码:

Dim MyObject As New TestClass() With {.Property1 = "Hello", .Property2 = 3}
Dim Serialized As String = JsonConvert.SerializeObject(MyObject)  

在上面两行执行之后,变量Serialized有以下值(这不是我所期望或想要的):

"Namespace1.TestClass"

当我完全删除类属性(只是类属性,而不是属性属性)然后执行相同的 2 行代码时,变量 Serialized 具有以下值(这就是我会期望):

{"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

【问题讨论】:

  • 对答案有任何反馈吗?

标签: vb.net serialization json.net


【解决方案1】:

我猜您不想更改您的TestClass,因为它一定是由某些工具生成的,我建议从中派生一个新类:

Imports Newtonsoft.Json

<JsonObject()>
Public Class OtherClass
    Inherits TestClass

End Class

并使用属性&lt;JsonObject()&gt;。这应该可以解决问题:

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

【讨论】:

  • LeftyX,谢谢你的回答。我会记住这一点 - 随着我们继续使用 Json 序列化,这可能会有所帮助。目前,我们不想创建和维护新对象,因此我们将使用自定义 IContractResolver。
【解决方案2】:

问题是你班级的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

【讨论】:

  • 布莱恩,感谢您的快速回复!我试过了,它与我们的代码完美配合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 2017-03-02
  • 2012-03-18
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
相关资源
最近更新 更多