【问题标题】:C#: To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object)C#:要实现 XML 可序列化,从 IEnumerable 继承的类型必须具有 Add(System.Object) 的实现
【发布时间】:2013-05-26 15:53:08
【问题描述】:

我有以下代码:

private static string FindAppointmentsAsXmlString(CalendarView calendar, ExchangeService serv)
{
    FindItemsResults<Appointment> appointments = serv.FindAppointments(WellKnownFolderName.Calendar, calendar);

    var serializer = new XmlSerializer(appointments.GetType());
    var writer = new StringWriter();

    try
    {
        serializer.Serialize(writer, appointments);
        Console.WriteLine(writer.GetStringBuilder().ToString());
        Console.ReadLine();
    }
    catch (Exception ex) 
    {
        Console.WriteLine(ex);
        Console.ReadLine();
    }

    return writer.GetStringBuilder().ToString();
}

在初始化序列化程序时,我得到了异常:

要实现 XML 可序列化,从 IEnumerable 继承的类型必须具有 在其继承层次结构的所有级别上实现 Add(System.Object)。

Microsoft.Exchange.WebServices.Data.FindItemsResults 未实现 Add(System.Object)。

我四处搜索,得出的结论是我必须添加一个公共 Add(Object obj) 方法。现在我不太确定这个方法应该包含什么或者什么时候被调用,有人能指出我正确的方向吗? Add方法是否需要手动添加每个约会?

我发现一些有用的链接: here here

非常感谢。

【问题讨论】:

    标签: c# serialization ienumerable add exchangewebservices


    【解决方案1】:

    我在创建分页结果对象时遇到了同样的问题。选择的答案基本上是正确的,但我想我会更好地格式化它并添加我自己的提示。

    基本上我实现了 Add,但我让它只是抛出一个异常来指导任何可能尝试调用它的未来开发人员,因为作为结果集,我希望它保持只读。序列化程序仍然可以正常工作,因此它显然在序列化时从不调用 Add 。我可能会遇到反序列化的问题,但由于这个对象纯粹是为了检索结果集,所以一切都应该很好。

    这是我添加到已实现 IEnumerable 的类中的内容:

        public void Add(T value)
        {
            throw new NotSupportedException("Add is not supported for paged results.  Try adding new items to the repository instead.");
        }
    

    【讨论】:

      【解决方案2】:

      您需要实现一个 Add 方法,当您反序列化 FindItemsResult 和它所包含的对象时,该方法可以将您的 IEnumerable 包含的类型的对象放回 IEnumerable 中。 IEnumerable 不像列表,因此反序列化的项目通常不能被放回某种容器中。没有办法知道如何实现一个实现 IEnumerable 的类,因此您必须为它显式编写一个 Add 方法。

      【讨论】:

      • 我实现了您所说的 Add 方法,不幸的是,仍然引发了相同的异常。 编辑: 我没有调用 Add 方法 - 我该怎么做? var serializer = new XmlSerializer(appointments.GetType().Add());?不行,这样不行……
      • 您的 add 方法是否将 Object 类的对象作为参数?我认为当您尝试反序列化实现 IEnumerable 的对象时,会自动调用 add 方法。
      【解决方案3】:

      Add() 方法应该有一个 IEnumerable 对象中元素类型的参数。例如,如果FindItemsResults 实现了IEnumerable&lt;T&gt;,那么您可以添加方法void Add(T value)。如果您希望FindItemsResults 是只读的,您可以通过ToList() 扩展方法将FindItemsResults 转换为List,并序列化该列表而不是FindItemsResults 对象本身。

      【讨论】:

      • 我已将 FindItemsResults 约会转换为 List 并对其进行序列化。但是,现在我遇到了一个异常:Microsoft.Exchange.WebServices.Data.Appointment 无法序列化,因为它没有参数化构造函数。有什么想法吗?
      • 您可能会收到此错误,因为 FindItemsResults 对象图中的某些内容不能使用 XmlSerializer 直接序列化。您可以尝试更强大的 DataContractSerializer,或者将 FindItemsResults 对象图转换为更简单的格式(POCO DTO)
      猜你喜欢
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      • 2012-08-27
      • 2016-06-18
      • 1970-01-01
      相关资源
      最近更新 更多