我有JsonSerializer
一個定製的包裝,看起來是這樣的:Newtonsoft JsonSerializer沒有設置正確的類型
public class MySerializer
{
JsonSerializer serializer;
public MySerializer()
{
serializer = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Auto,
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
ContractResolver = new DefaultContractResolver()
};
}
public byte[] Serialize<T>(T value)
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8))
serializer.Serialize(new JsonTextWriter(streamWriter), value);
return memoryStream.ToArray();
}
}
public T Deserialize<T>(byte[] serialized)
{
using (MemoryStream memoryStream = new MemoryStream(serialized))
{
using (var streamReader = new StreamReader(memoryStream, Encoding.UTF8))
return serializer.Deserialize<T>(new JsonTextReader(streamReader));
}
}
}
它通常工作正常,我真的需要使用JsonSerializer
因爲在項目的限制。我不尋找任何其他序列化器。
我想序列化的類/反序列化看起來是這樣的:
public class Person
{
public House LivingArrangement { get; set; } = new TreeHouse();
}
public class House
{
public int NumberOfBeds { get; set; }
public virtual bool IsInTree => false; // just to show the issue
}
public class TreeHouse : House
{
public override bool IsInTree => true; // just to show the issue
}
在現實世界中它要複雜得多,但是這僅僅是爲了說明問題。請注意,如果沒有其他設置,則每個Person
都生活在TreeHouse
中。這是非常重要的,並且由於我的項目中存在其他限制而無法更改。類啓動時,類型必須設置爲TreeHouse
。它不能是null
。
問題是,當類被反序列化時,類型爲TreeHouse
,即使我明確將其設置爲House
。請參閱下面的測試。
[TestMethod]
public void Serialization_Test()
{
var item = new Person();
item.LivingArrangement = new House(); // This person lives in a house.
item.LivingArrangement.NumberOfBeds = 2;
var serializer = new MySerializer();
var serializedItem = serializer.Serialize(item);
var deserializedItem = serializer.Deserialize<Person>(serializedItem);
Console.WriteLine(deserializedItem.LivingArrangement.GetType()); // Output: UnitTestProject1.TreeHouse
// Works fine!
Assert.IsTrue(item.LivingArrangement.NumberOfBeds == 2);
// The assert fails.
Assert.IsFalse(deserializedItem.LivingArrangement.IsInTree);
// The assert fails.
Assert.AreEqual(deserializedItem.LivingArrangement.GetType(), typeof(House));
}
爲什麼JsonSerializer
保持TreeHouse
,而不是發起的House
一個新的實例?我該如何解決它,但仍然使用JsonSerializer?