我正在使用ServiceStack.Text来序列化/反序列化对象,然后将它们存储在Redis中,但是我遇到了一些不会按预期反序列化的对象。
我有一个基类型(遗留代码的位,许多项目使用此基类型),其属性类型为object。后来添加了基本类型的通用版本,将属性公开为泛型类型。
使用ServiceStack.Text序列化和反序列化泛型类型设置基类(类型对象)上的属性,而不是派生类上更具体的类型。
重现错误的简单控制台应用程序如下:
class Program
{
public class Base<T> : Base
{
//hide the Value property on the base class
public new T Value { get; set; }
}
public class Base
{
public object Value { get; set; }
}
static void Main(string[] args)
{
var a = new Base<List<string>>()
{
Value = new List<string>() { "one", "two", "three" },
};
var serialized = TypeSerializer.SerializeToString(a);
var deserialized = TypeSerializer.DeserializeFromString<Base<List<string>>>(serialized);
//throws a null ref exception
Console.WriteLine(deserialized.Value.Count);
}
}
在反序列化后设置断点,Visual Studio将base.Value显示为List&lt; string&gt;使用序列化列表的值,但是我的Base上的Value属性&lt; List&lt; String&gt;&gt; class为null。
Screenshot of debugger in Visual Studio
有没有办法配置TypeSerializer(或JsonSerializer)来正确设置更具体的属性而不是基类的属性?
感谢任何帮助。
<小时/> 的更新
基于答案,我通过使Base<T>
和Base
继承自新的抽象基类来解决它,如下所示:
public abstract class DummyBase
{
public string Test { get; set; } = "Test";
}
public class BaseResponse<T> : DummyBase
{
public T Value { get; set; }
}
public class BaseResponse : DummyBase
{
public object Value { get; set; }
}
答案 0 :(得分:1)
即使Base.Value被隐藏,它仍然可以被反射看到(例如a.GetType().GetProperties()
。这可能就是问题。
以下似乎有效。 Base<T>
中的getter和setter只包装Base.Value
。要使ServiceStack将字符串反序列化为正确的类型,必须DummyBase<T>
。
class Program
{
public static void Main (string[] args)
{
var a = new Base<List<string>>()
{
Value = new List<string> { "one", "two", "three" },
};
var serialized = TypeSerializer.SerializeToString(a);
var deserialized = TypeSerializer.DeserializeFromString<DummyBase<List<string>>>(serialized);
// no longer throws a null ref exception
Console.WriteLine(deserialized.Value.Count);
}
}
public class DummyBase<T>
{
public T Value { get; set; }
}
public class Base<T> : Base
{
public new T Value
{
get { return (T)base.Value; }
set { base.Value = value; }
}
}
public class Base
{
public object Value { get; set; }
}
当然,如果Base<T>
没有从Base
继承,则不需要这一切。