使用JSON.NET与ExpandableObjectConverter的问题

我定义了以下类:

  Public Class Vector3  Public Property X As Double  Public Property Y As Double  Public Property Z As Double Public Overrides Function ToString() As String Return String.Format("({0}, {1}, {2})", Format(X, "0.00"), Format(Y, "0.00"), Format(Z, "0.00")) End Function End Class 

使用DataContractJsonSerializer我按预期收到以下JSON:

 { "Vector": { "X": 1.23, "Y": 4.56, "Z": 7.89 } } 

但是,JSON.NET产生:

 { "Vector": "(1.23, 4.56, 7.89)" } 

如果我从类中删除ExpandableObjectConverter属性,JSON.NET会按预期生成结果(与DataContractJsonSerializer相同)。

不幸的是,我需要ExpandableObjectConverter以便该类使用属性网格。

有没有办法告诉JSON.NET忽略ExpandableObjectConverters

我更喜欢使用JSON.NET而不是DataContractJsonSerializer因为将枚举序列化为字符串表示要容易得多。

虽然我很欣赏Rivers的回答,但我真的在寻找一种自动忽略所有可扩展对象转换器的解决方案(比如DataContractJsonSerializer),而不是为每个违规类构建一个自定义JsonConverter。

我找到了以下两种解决方案:

  1. 使用内置的DataContractJsonSerializer(以牺牲JSON.NET的其他一些便利为代价)。
  2. 使用自定义ExpandableObjectConverter(参见下文)。

由于默认的ExpandableObjectConverter支持转换为/从字符串转换,因此JSON.NET使用字符串序列化类。 为了抵消这种情况,我创建了自己的可扩展对象转换器,它不允许转换为字符串。

 Imports System.ComponentModel Public Class SerializableExpandableObjectConverter Inherits ExpandableObjectConverter Public Overrides Function CanConvertTo(context As System.ComponentModel.ITypeDescriptorContext, destinationType As System.Type) As Boolean If destinationType Is GetType(String) Then Return False Else Return MyBase.CanConvertTo(context, destinationType) End If End Function Public Overrides Function CanConvertFrom(context As System.ComponentModel.ITypeDescriptorContext, sourceType As System.Type) As Boolean If sourceType Is GetType(String) Then Return False Else Return MyBase.CanConvertFrom(context, sourceType) End If End Function End Class 

应用上面的转换器与JSON.NET和属性网格控件完美配合!

由于您正在指定TypeConverter,Json.net使用它。 要解决这个问题,使用LINQ to Json创建一个JsonConverter以使用您需要的格式:

 Public Class Vector3Converter Inherits JsonConverter Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer) Dim vector = DirectCast(value, Vector3) serializer.Serialize(writer, New JObject() From { _ {"X", vector.X}, _ {"Y", vector.Y}, _ {"Z", vector.Z} _ }) End Sub Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object Dim jObject = serializer.Deserialize(Of JObject)(reader) Return New Vector3() With { _ Key .X = CDbl(jObject("X")), _ Key .Y = CDbl(jObject("Y")), _ Key .Z = CDbl(jObject("Z")) _ } End Function Public Overrides Function CanConvert(objectType As Type) As Boolean Return objectType = GetType(Vector3) End Function End Class 

然后,将其分配给您的类型:

  _  _  _ Public Class Vector3 End Class 

我最初使用C#,并使用在线转换器VB,所以它可能有点偏。