说我有以下课程:
[DataContract]
class Entry<T>
{
[DataMember]
public T Data { get; set; }
}
[DataContract]
class DataList<T>
{
[DataMember]
public IList<T> Collection { get; set; }
}
[DataContract]
[KnownType(typeof(User))]
class ExtendedDataList : DataList<object>
{
[DataMember]
public string SomeExtraParameter { get; set; }
}
[DataContract]
class User
{
[DataMember]
public string Name { get; set; }
}
我已将KnownTypeAttribute
应用于ExtendedDataList
,因为该类扩展了常规类型object
的基类,并且它将在列表中存储不同类型的对象。在此示例中,我标记了一种已知类型的User
,因为我知道它包含User
个对象。
这是序列化代码:
var user = new User { Name = "Bob" };
var users = new ExtendedDataList { Collection = new List<object> { user } };
serialize(users);
与
static void serialize<T>(T obj)
{
var entry = new Entry<T>();
entry.Data = obj;
var stream = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(Entry<T>));
serializer.WriteObject(stream, entry);
stream.Seek(0, SeekOrigin.Begin);
var r = new StreamReader(stream);
var s = r.ReadToEnd();
System.Diagnostics.Debug.WriteLine(s);
}
行[{1}}会抛出serializer.WriteObject(stream, entry);
,表示不期望类型SerializationException
,我应该使用User
来指定它。但我做了(间接)!
我该如何使这项工作?我无法将KnownTypeAttribute
移到KnownType
类,因为它需要是通用的。为什么不能Entry<T>
看到DataContractJsonSerializer
将ExtendedDataList
指定为已知类型?
答案 0 :(得分:0)
我找到了一种让它工作的方法,但仍然无法解释为什么DataContractJsonSerializer
忽略了我已应用于KnownType
的{{1}}属性< / em>的
ExtendedDataList
似乎不够聪明,无法注意到我在DataContractJsonSerializer
类中指定的KnownType
属性;显然它只尊重我附加到ExtendedDataList
类的已知类型,因为Entry<T>
是我给typeof(Entry<T>)
的构造函数的类型
我希望DataContractJsonSerializer
保持一般性,我不想把它与各种Entry<T>
属性混在一起。因此,我使用以下类定义:
KnownType
这使用反射来获取附加到内部类型[DataContract]
[KnownType("KnownTypes")]
class Entry<T>
{
[DataMember]
public T Data { get; set; }
public static IEnumerable<Type> KnownTypes()
{
var attrs = typeof(T).GetTypeInfo().GetCustomAttributes<KnownTypeAttribute>();
return attrs.Select(attr => attr.Type);
}
}
的{{1}}属性,然后将这些类型传递给序列化KnownType
的任何数据协定序列化程序。
注意:需要T
和Entry<T>
。