考虑使用DataContractAttribute属性对其进行标记

本文关键字:属性 DataContractAttribute | 更新日期: 2023-09-27 18:03:15

我有这样的代码:

IList<Type> lista = new List<Type>();
lista.Add(typeof(Google.GData.YouTube.YouTubeEntry));
using (FileStream writer = new FileStream("c:/temp/file.xml", FileMode.Create, FileAccess.Write))
{
    DataContractSerializer ser = new DataContractSerializer(videoContainer.GetType(), lista);
    ser.WriteObject(writer, videoContainer);
}

生成以下异常:Type 'Google.GData.Client.AtomUri' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

我不能编辑Google.GData.Client.AtomUri添加这些属性(它是一个库)。

那么,我该如何解决这个问题呢?

考虑使用DataContractAttribute属性对其进行标记

我不能编辑Google.GData.Client.AtomUri添加这些属性(它是一个库)。

那么你有两个选择:

  • 写一个单独的DTO层,其中可序列化的;这通常是微不足道的,当遇到任何序列化器的问题时,这几乎总是我的首选路线。意思是:编写自己的类型集,看起来与GData类大致相似,它们以适合您选择的序列化器的方式进行装饰和构造-并编写少量代码行来在它们之间进行映射
  • DataContractSerializer构造函数使用多个重载中的一个来指定附加信息;坦率地说,这通常只会让你陷入一个繁琐的迷宫,用越来越多的笨拙代码告诉它,直到它几乎可以工作;DTO更易于维护

如果您所追求的只是属性的值,那么您可以使用基本反射并显示它们。这将显示给定对象的所有属性值,包括遍历集合。虽然不是世界上最好的代码,但对于读取对象来说,这是一个很好的快速解决方案。

static void ShowProperties(object o, int indent = 0)
{
    foreach (var prop in o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string))
        {
            Console.WriteLine("{0}{1}:", string.Empty.PadRight(indent), prop.Name);
            var coll = (IEnumerable)prop.GetValue(o, null);
            if (coll != null)
            {
                foreach (object sub in coll)
                {
                    ShowProperties(sub, indent + 1);
                }
            }
        }
        else
        {
            Console.WriteLine("{0}{1}: {2}", string.Empty.PadRight(indent), prop.Name, prop.GetValue(o, null));
        }
    }
    Console.WriteLine("{0}------------", string.Empty.PadRight(indent));
}