上下文:我需要传递一个包含大量属性/字段的对象(从中间层到UI层)。在这个属性列表中,一个是Version类型,它没有从JSON字符串格式正确反序列化。我在XML上选择了JSON格式,因为字符串的JSON序列化将返回短字符串结果。
问题: System.Version无法正确反序列化。我尝试了两种不同的.NET库。以下是每个代码片段:
使用ServiceStack .NET library的代码段1:
var version = new Version(1, 2, 3, 0);
string reportJSON = JsonSerializer.SerializeToString<Version>(version);
//{"Major":1,"Minor":2,"Build":3,"Revision":0,"MajorRevision":0,"MinorRevision":0}
Version report2 = JsonSerializer.DeserializeFromString<Version>(reportJSON);
string reportJSON2 = JsonSerializer.SerializeToString<Version>(report2);
//{"Major":0,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1}
代码片段2使用Newtonsoft .NET library但结果相同:
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<Version>(reportJSON);
string reportJSON2 = JsonConvert.SerializeObject(report2);
//{"Major":0,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1}
如何解决这个问题?或者哪个其他JSON.NET库可以正常工作?
答案 0 :(得分:18)
Newtonsoft.Json
库在Newtonsoft.Json.Converters
命名空间中提供了一组常用转换器,包括可用于序列化和反序列化{{1}的 VersionConverter
}。
请注意,您必须使用System.Version
进行序列化和反序列化,但。
那是因为标准序列化会生成eg.:{ {1}}而VersionConverter
反序列化需要一个简单的字符串,如{"Major":1,"Minor":2,"Build":3,"Revision":0,"MajorRevision":0,"MinorRevision":0}
。
所以用法是:
VersionConverter
我不确定包含该转换器的"1.2.3"
的第一个版本是什么。我有它,它是5.0.6。
答案 1 :(得分:9)
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<Dictionary<string, int>>(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<Version>(json, new VersionConverter());
Json.NET决定是否使用您指定的转换器之一。因此,您始终可以指定转换器,如下所示。如果Json.NET与SomeClass
中的类型匹配,则会使用其中一个转换器。
var result = JsonConvert.DeserializeObject<SomeClass>(json, new VersionConverter());