DataContractJsonSerializer
有一个特定的格式,它存储关于多态类型已知类型信息的提示,可以通过一些测试来发现。我按原样复制并粘贴了您的类,并创建了以下测试代码:
public static class DataContractJsonSerializerPolymorphismTest
{
public static void Test()
{
var a1 = new A() { s1 = "A" };
var b1 = new B() { s2 = "B" };
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(IObject));
var jsona1 = DataContractJsonSerializerHelper.GetJson(a1, serializer);
var jsonb1 = DataContractJsonSerializerHelper.GetJson(b1, serializer);
Debug.WriteLine(jsona1);
Debug.WriteLine(jsonb1);
var newa1 = DataContractJsonSerializerHelper.GetObject<IObject>(jsona1, serializer);
Debug.Assert(newa1.GetType() == a1.GetType());
}
}
通过此操作,以下JSON文件被创建:
{"__type":"A:#Tile.DataContractJsonSerializerPolymorphism","s1":"A"}
{"__type":"B:#Tile.DataContractJsonSerializerPolymorphism","s2":"B"}
Tile.DataContractJsonSerializerPolymorphism
是我测试应用程序中的CLR名称空间。因此,可以看到已知类型信息被放置在了这个额外的JSON属性
__type
中。如果您也在客户端使用
DataContractJsonSerializerHelper
,那么您永远不会知道这一点,因为通信只需正常工作。但是,您正在使用没有这种逻辑的
JSON.stringify()
。因此,您可能需要在客户端手动添加
"__type":"DataContractName:DataContractNamespace"
属性。
有关多态类型格式的更多信息可以在
此处找到。(仅在找到隐藏的
__type
参数并获得额外的Google搜索词汇后,我才跟踪到这份文档。)
附带说明一下,以下是我在测试代码中使用的帮助类:
public static class DataContractJsonSerializerHelper
{
private static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
}
public static string GetJson<T>(T obj, DataContractJsonSerializer serializer) where T : class
{
using (var memory = new MemoryStream())
{
serializer.WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
{
return reader.ReadToEnd();
}
}
}
public static string GetJson<T>(T obj) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return GetJson(obj, serializer);
}
public static T GetObject<T>(string json) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return GetObject<T>(json, serializer);
}
public static T GetObject<T>(string json, DataContractJsonSerializer serializer) where T : class
{
T obj = null;
using (var stream = GenerateStreamFromString(json))
{
obj = (T)serializer.ReadObject(stream);
}
return obj;
}
}
IObject
更改为一个interface
,会发生什么? - oatsoda