我使用ServiceStack将一些对象序列化和反序列化为JSON。考虑这个例子:
public class Container
{
public Animal Animal { get; set; }
}
public class Animal
{
}
public class Dog : Animal
{
public void Speak() { Console.WriteLine("Woof!"); }
}
var container = new Container { Animal = new Dog() };
var json = JsonSerializer.SerializeToString(container);
var container2 = JsonSerializer.DeserializeFromString<Container>(json);
((Dog)container.Animal).Speak(); //Works
((Dog)container2.Animal).Speak(); //InvalidCastException
最后一行抛出一个InvalidCastException,因为Animal字段被实例化为Animal类型,而不是Dog类型。有没有什么方法可以让ServiceStack保留这个特定实例属于Dog类型的信息?
发布于 2012-05-25 16:21:18
您只序列化了动物对象的属性,而不管序列化的对象是不是狗。即使你给狗类添加了一个公共属性,比如"Name",它也不会被序列化,所以当你反序列化时,你只会拥有一个"Animal“类的属性。
如果你把它改成下面的代码,它就会起作用;
public class Container<T> where T: Animal
{
public T Animal { get; set; }
}
public class Animal
{
}
public class Dog : Animal
{
public void Speak() { Console.WriteLine("Woof!"); }
public string Name { get; set; }
}
var c = new Container<Dog> { Animal = new Dog() { Name = "dog1" } };
var json = JsonSerializer.SerializeToString<Container<Dog>>(c);
var c2 = JsonSerializer.DeserializeFromString<Container<Dog>>(json);
c.Animal.Speak(); //Works
c2.Animal.Speak();
发布于 2016-09-28 23:01:06
也许是离题的,但Newtonsoft序列化程序可以做到这一点,包括以下选项:
serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
它将使用对象的强类型在json中创建一个名为$type的属性。当您调用反序列化程序时,该值将用于再次构建具有相同类型的对象。下一个测试使用带强类型的newtonsoft,而不是ServiceStack
[TestFixture]
public class ServiceStackTests
{
[TestCase]
public void Foo()
{
FakeB b = new FakeB();
b.Property1 = "1";
b.Property2 = "2";
string raw = b.ToJson();
FakeA a=raw.FromJson<FakeA>();
Assert.IsNotNull(a);
Assert.AreEqual(a.GetType(), typeof(FakeB));
}
}
public abstract class FakeA
{
public string Property1 { get; set; }
}
public class FakeB:FakeA
{
public string Property2 { get; set; }
}
https://stackoverflow.com/questions/10750571
复制相似问题