【问题标题】:WCF DataContract - unable to return complex typeWCF DataContract - 无法返回复杂类型
【发布时间】:2012-02-01 19:36:13
【问题描述】:

我有一个 WCF 服务,它具有返回对象集合 IEnumerable<T> 的方法,还有一个复杂类型 OrganizationCollection,它有几个属性,每个属性都是不同类型的 IEnumerable<T>。我相信我已经正确设置了我的服务合同,并正确定义了我的类型 DataContract / DataMember。返回OrganizationCollection 的方法因异常而失败。我知道该方法有效,因为我有对其进行测试的单元和集成测试。只有在使用实时和已部署的服务运行时才会失败。我什至将类型指定为ServiceKnownType,但无济于事。我需要做些什么来配置服务以便能够返回复杂类型,例如OrganizationCollection

注意:WCF 服务使用 basicHttpBinding 运行,并位于 Windows 服务的 ServiceHost 中。

[System.ServiceModel.CommunicationException] {"接收到http://localhost:8799/MyService 的 HTTP 响应时发生错误。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于 HTTP 请求上下文被服务器中止(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。"} System.ServiceModel.CommunicationException

[ServiceBehavior(IncludeExceptionDetailInFaults = true, AutomaticSessionShutdown = false, InstanceContextMode = InstanceContextMode.Single)]
[ServiceKnownType(typeof(OrganizationCollection))]
public class MyService: IClientService
{ 
    // ...
}

[ServiceContract]
public interface IClientService
{
    // This works:
    [OperationContract]
    IEnumerable<BookSvc> GetBooks(DateTime sinceDate);

    // This fails, with the above exception:
    [OperationContract]
    OrganizationCollection GetOrganizations(DateTime sinceDate);
}

BookSvc[DataContract] 定义,每个属性都有[DataMember]。教师和学生课程也是如此。属性都是原始类型。 OrganizationCollection 定义为:

[DataContract]
public class OrganizationCollection
{
    [DataMember]
    public IEnumerable<Teacher> Teachers { get; set; }

    [DataMember]
    public IEnumerable<Student> Students { get; set; }
}

【问题讨论】:

  • 第一:您的TeacherStudent 课程是否也标记为[DataContract]?第二:您是否尝试将属性类型更改为Teacher[]Student[]?无论如何,它们都需要完全枚举,然后才能通过 WCF 返回。
  • @Douglas,1. 是的,教师和学生被标记为 [DataContract]。 2. 我可以试试,但是我执行时确实有效的方法也返回为 IEnumerable,但我确实意识到它们是独立的返回值,而不是复杂类型的一部分。
  • 我不确定;我会把它留给其他人来给出一个明智的答复。我只是建议了一些你可以尝试快速修复的东西。但是,我认为IEnumerable&lt;T&gt; 无论如何都不是这种场景的好设计选择;复杂类型应该被限制为持有一个 populated 集合。如果你想选择最低的界面,我更喜欢ICollection&lt;T&gt;
  • 你可能想在这里阅读:Collection Types in Data Contracts.

标签: c# wcf web-services ienumerable


【解决方案1】:

有两种选择:

  1. 具体集合类型(List等)应作为返回值,为WCF提供序列化机制(Collection Types in Data Contracts, MSDN)。

  2. 使用已知数据类型 (Data Contract Known Types, MSDN)。

【讨论】:

  • GetBooks() 方法中返回 IEnumerable 时为什么不需要具体的集合类型?
  • 切换到硬 List 类型就可以了。仍然好奇为什么需要这样做。在所有情况下使用 List 可能是最安全的。
  • 很高兴它对您有所帮助。此处描述了规则:Collection Types in Data Contracts.
猜你喜欢
  • 2018-06-26
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多