Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DataContractJsonSerializer抛出SerializationException,即使I';我用KnownTypeAttribute指定了它_C#_.net_Windows Runtime_Windows Phone 8.1 - Fatal编程技术网

C# DataContractJsonSerializer抛出SerializationException,即使I';我用KnownTypeAttribute指定了它

C# DataContractJsonSerializer抛出SerializationException,即使I';我用KnownTypeAttribute指定了它,c#,.net,windows-runtime,windows-phone-8.1,C#,.net,Windows Runtime,Windows Phone 8.1,假设我有以下课程: [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)

假设我有以下课程:

[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; }
}

静态无效序列化(T obj)
{
var entry=新条目();
条目。数据=obj;
var stream=newmemoryStream();
var serializer=newdatacontractjsonserializer(typeof(Entry));
serializer.WriteObject(流、条目);
stream.Seek(0,SeekOrigin.Begin);
var r=新的StreamReader(stream);
var s=r.ReadToEnd();
系统诊断调试写入线;
}
serializer.WriteObject(流,条目)
抛出一个
SerializationException
表示类型
用户
不是预期的,我应该使用
KnownTypeAttribute
来指定它。但我(间接地)做到了


我怎样才能做到这一点?我无法将
KnownType
移动到
Entry
类,因为它需要是通用的。为什么
DataContractJsonSerializer
看不到
ExtendedDataList
用户指定为已知类型?

我找到了一种方法让它工作,但它仍然无法解释为什么
DataContractJsonSerializer
忽略了我应用于
ExtendedDataList
KnownType
属性

似乎
DataContractJsonSerializer
不够聪明,没有注意到我在
ExtendedDataList
类上指定的
KnownType
属性;显然,它只尊重我附加到
Entry
类的已知类型,因为
typeof(Entry)
是我给
DataContractJsonSerializer的构造函数的类型

我希望
Entry
保持通用性,并且我不想在其中乱扔各种
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);
    }
}
[DataContract]
[KnownType(“KnownTypes”)]
班级报名
{
[数据成员]
公共T数据{get;set;}
公共静态IEnumerable KnownTypes()
{
var attrs=typeof(T).GetTypeInfo().GetCustomAttributes();
返回attrs.Select(attr=>attr.Type);
}
}
这使用反射来获取附加到内部类型
T
KnownType
属性,然后将这些类型传递给序列化
条目的任何数据协定序列化程序

注意:需要
使用System.Linq
使用System.Reflection

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);
}
[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);
    }
}