为什么JSON字符串中的System.Version没有正确反序列化?

上下文:我需要传递一个包含大量属性/字段的对象(从中间层到UI层)。 在这个属性列表中,一个是Version类型,它没有从JSON字符串格式正确反序列化。 我在XML上选择了JSON格式,因为字符串的JSON序列化将返回短字符串结果。

问题:System.Version没有正确反序列化。 我尝试了两种不同的.NET库。 以下是每个代码段:

使用ServiceStack .NET库的代码片段1:

var version = new Version(1, 2, 3, 0); string reportJSON = JsonSerializer.SerializeToString(version); //{"Major":1,"Minor":2,"Build":3,"Revision":0,"MajorRevision":0,"MinorRevision":0} Version report2 = JsonSerializer.DeserializeFromString(reportJSON); string reportJSON2 = JsonSerializer.SerializeToString(report2); //{"Major":0,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1} 

Code Snippet 2使用Newtonsoft .NET库但结果相同:

  var version = new Version(1, 2, 3, 0); string reportJSON = JsonConvert.SerializeObject(version); //{"Major":1,"Minor":2,"Build":3,"Revision":0,"MajorRevision":0,"MinorRevision":0} Version report2 = JsonConvert.DeserializeObject(reportJSON); string reportJSON2 = JsonConvert.SerializeObject(report2); //{"Major":0,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1} 

如何解决这个问题? 或者哪个其他JSON.NET库可以正常工作?

Newtonsoft.Json库在Newtonsoft.Json.Converters命名空间中提供了一组常用转换器,包括可用于序列化和反序列化System.VersionVersionConverter

但请注意,您必须使用VersionConverter进行序列化和反序列化
这是因为标准序列化将生成例如: {"Major":1,"Minor":2,"Build":3,"Revision":0,"MajorRevision":0,"MinorRevision":0}VersionConverter反序列化期望一个简单的字符串,如"1.2.3"

所以用法是:

 using Newtonsoft.Json; using Newtonsoft.Json.Converters; string s = JsonConvert.SerializeObject(version, new VersionConverter()); Version v = JsonConvert.DeserializeObject(s, new VersionConverter()); 

我不确定包含该转换器的Newtonsoft.Json的第一个版本是什么。 我有它,它是5.0.6。

Version类的属性没有setter。 他们只返回相应私有字段的值。 因此,解串器无法更改其值。

但是使用Json.NET,您可以编写一个自定义转换器类来处理Version类的反序列化。

注意:此代码未经过良好测试…

 public class VersionConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // default serialization serializer.Serialize(writer, value); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // create a new Version instance and pass the properties to the constructor // (you may also use dynamics if you like) var dict = serializer.Deserialize>(reader); return new Version(dict["Major"], dict["Minor"], dict["Build"], dict["Revision"]); } public override bool CanConvert(Type objectType) { return objectType == typeof(Version); } } 

然后你必须指定你想要使用转换器:

 var v = new Version(1, 2, 3, 4); string json = JsonConvert.SerializeObject(v); var v2 = JsonConvert.DeserializeObject(json, new VersionConverter()); 

Json.NET决定是否使用您指定的转换器之一。 因此,您始终可以指定转换器,如下所示。 如果Json.NET与SomeClass中的类型匹配,它将使用您的一个转换器。

 var result = JsonConvert.DeserializeObject(json, new VersionConverter());