WCF OperationContract - 我应该公开哪种通用集合类型?

Kla*_*sen 9 c# collections wcf operationcontract

我有一个WCF Web服务,它有一个返回泛型集合的方法.现在,我的问题是:我应该公开为ICollection<T>,List<T>,IList<T>,IEnumerable<T>或其他什么东西?

我想这List<T>不可能的,因为我想避免CA1002错误,但底层类型将是一个List<T>.

我真的很想听听你对此的看法,最好能够很好地解释你为什么这么想.

提前致谢

Aar*_*ght 17

请记住,CA1002等错误确实适用于库.WCF服务不是库,它是通过SOAP,REST等序列化所有内容的端点.

您会发现,如果您尝试公开诸如ICollection<T>或之类的接口IList<T>,您将收到无法序列化类型的错误.事实上,List<T>这可能是最好的选择.当客户端生成代理时,默认情况下它最终会成为一个数组,并且很多人(如果不是大多数人)将其更改为a List<T>,因此90%的时间,无论您选择如何公开它,都是类型无论如何客户会看到.

我会注意到,一般来说,最好不要从WCF操作或Web服务"返回"集合.创建包含所需集合的代理类更为常见,并将其返回,即:

[OperationContract]
OrdersResult GetOrders(OrderRequest request);
Run Code Online (Sandbox Code Playgroud)

代理类可能如下所示:

[DataContract]
public class OrdersResult
{
    [DataMember]
    public List<Order> Orders { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这样,如果您决定需要向请求或响应添加更多数据,则可以在不对客户端进行重大更改的情况下执行此操作.


附录:WCF的真正问题是WCF不知道特定类型仅用于出站数据. 当通过WCF服务公开任何类时,WCF假定它可以是请求响应的一部分,并且如果它是请求的一部分,则该类型必须是具体的并且不能是不可变的.这就是所有其他愚蠢限制的原因,比如要求财产制定者.

你在这里别无选择,只能使用具体的可变集合类型,在大多数情况下,这意味着数组或通用列表.


Mar*_*ann 6

在我看来,暴露序列的服务和数据合同应该清楚地表明这些序列是不可变的,因为它们作为DTO在线路上传播.在从不同层接收的序列中添加和删除它并没有多大意义.相反,您希望读取该数据并对其执行某些操作.

鉴于此,我真的更愿意使用IEnumerable<T>,但不幸的是,这对WCF不起作用.你可以得到各种奇怪的错误,特别是在延迟执行时,所以(在WCF上下文中)最好远离那些.

这实际上只留下了数组,因为它们最好地传达了其余选项的意图.