2

我正在尝试使用 ServiceStack.Redis 并且我注意到当我存储一个对象时,它的成员是从另一个对象继承的对象并稍后尝试获取它我得到空值。

我检查并发现 ServiceStack.Redis 正在使用 ServiceStack.JsonSerializer 所以我尝试创建一个测试用例:

class Program
{
    public class ClassA
    {
        public string Id;

        public Dictionary<string, ClassB> dic = new Dictionary<string, ClassB>();
    }

    public class ClassB
    {
        public string Id;   
    }

    public class ClassC : ClassB
    {
        public object C;
    }

    public class ClassD
    {
        public string Id;
    }

    static void Main(string[] args)
    {
        ClassA t = new ClassA();
        t.Id = Guid.NewGuid().ToString("n");
        t.dic.Add("AAA", new ClassC());
        t.dic["AAA"].Id = Guid.NewGuid().ToString("n");
        ((ClassC)t.dic["AAA"]).C = new ClassD();
        ((ClassD)((ClassC)t.dic["AAA"]).C).Id = Guid.NewGuid().ToString("n");

        ServiceStack.Text.JsConfig.IncludeNullValues = true;
        ServiceStack.Text.JsConfig.IncludePublicFields = true;
        ServiceStack.Text.JsConfig.IncludeTypeInfo = true;
        ServiceStack.Text.JsConfig.MaxDepth = int.MaxValue;

        Console.WriteLine("before SerializeToString data is:");
        if (string.IsNullOrEmpty(((ClassD)((ClassC)t.dic["AAA"]).C).Id))
        {
            Console.WriteLine("wrong");
        }
        else
        {
            Console.WriteLine("right");
        }

        string a = JsonSerializer.SerializeToString<ClassA>(t);

        ClassA t2 = JsonSerializer.DeserializeFromString<ClassA>(a);

        Console.WriteLine("after SerializeToString data is:");
        if (((ClassC)t2.dic["AAA"]).C == null ||
            string.IsNullOrEmpty(((ClassD)((ClassC)t2.dic["AAA"]).C).Id))
        {
            Console.WriteLine("wrong");
        }
        else
        {
            Console.WriteLine("right");
        }

        Console.ReadLine();
    }
}

当它不工作时,我可以找到一个更简单的案例......

如您所见,ClassC 有一个object类型的成员,并且该类从 ClassB继承(如果您删除继承或为成员提供另一种类型,它将起作用)。

序列化之前的数据是“正确的”,反序列化之后的数据是“错误的”-> 成员为空。

你能帮我吗?

4

1 回答 1

5

默认情况下,ServiceStack 只序列化公共属性。要序列化公共字段,您还需要设置:

JsConfig.IncludePublicFields = true;

此外,如果要使用继承,则需要使子类抽象或接口。有关更多信息,请参阅此答案

于 2013-06-28T07:54:08.330 回答