以下是关于问题解决方案的我的想法:
问题:
Json.Net的自定义反序列化API不够透明,即会影响我的类层次结构。
实际上,如果您的项目中有10-20个类,这并不是问题,但是如果您的项目中有成千上万个类,您需要遵守Json.Net要求来符合OOP设计,这将让您很不满意。
Json.Net对POCO对象非常好用,这些对象在创建后进行填充(初始化)。但是,并非所有情况下都是如此,有时您的对象是在构造函数内初始化的。为了使该初始化发生,您需要传递“正确”的参数。这些“正确”的参数可以存在于序列化文本中,或者它们可以在之前某个时刻被创建和初始化。不幸的是,Json.Net在反序列化期间对于它不理解的参数传递默认值,在我的情况下总是导致ArgumentNullException。
解决方案:
这里提供了一种方法,可以在反序列化过程中使用任何一组参数(无论是序列化还是非序列化),实现自定义对象创建,主要问题是这种方法不太优化,每个需要自定义反序列化的对象需要两个反序列化阶段,但是它仍然可行,可以按照您的需求反序列化对象,具体方法如下:
首先,我们将CustomCreationConverter类重组如下:
public class FactoryConverter<T> : Newtonsoft.Json.JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
T value = CreateAndPopulate(objectType, serializer.Deserialize<Dictionary<String, String>>(reader));
if (value == null)
throw new JsonSerializationException("No object created.");
return value;
}
public abstract T CreateAndPopulate(Type objectType, Dictionary<String, String> jsonFields);
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override bool CanWrite
{
get
{
return false;
}
}
}
接下来我们创建一个工厂类,用于创建 Foo 实例:
public class FooFactory : FactoryConverter<Foo>
{
public FooFactory(Bar bar)
{
this.Bar = bar;
}
public Bar Bar { get; private set; }
public override Foo Create(Type objectType, Dictionary<string, string> arguments)
{
return new Foo(Bar, arguments["X"], arguments["Y"]);
}
}
以下是示例代码:
var bar = new Bar("BarObject");
var fooSrc = new Foo
(
bar,
"A", "B"
);
var str = JsonConvert.SerializeObject(fooSrc);
var foo = JsonConvert.DeserializeObject<Foo>(str, new FooFactory(bar));
Console.WriteLine(str);
在这种情况下,foo包含了一个参数,我们需要在反序列化期间传递给Foo构造函数。