WCF 代理返回数组而不是列表,即使集合类型 == Generic.List

Posted

技术标签:

【中文标题】WCF 代理返回数组而不是列表,即使集合类型 == Generic.List【英文标题】:WCF Proxy Returning Array instead of List EVEN THOUGH Collection Type == Generic.List 【发布时间】:2012-11-10 20:54:06 【问题描述】:

我有一个 VS 2010 解决方案,其中包含一个 WCF 库项目和另一个使用该 Web 服务的项目。 VS 2012开启后,升级了。

代理现在将 List 类型作为数组返回,即使 CollectionMappings 明确设置为 Generic.List。

会发生什么?

其他人也有类似的问题here,但他正在从 VS 2012 降级到 VS 2010。

编辑:我仔细检查了,Reference.svcmap 包含:

<CollectionMappings>
  <CollectionMapping TypeName="System.Collections.Generic.List`1" Category="List" />
</CollectionMappings>

但 Reference.cs 包含以下内容:

 public xxx.ServiceReference1.ADUser[] get_ADUsers;

在网络服务中是:

 public List<ADUser> get_ADUsers(string wildcard, string sortexp, string sortorder)

更多信息(2012 年 12 月 12 日添加):

在 VS2010 中创建的解决方案在另一台 PC 上运行良好。它已从该 PC 检入 TFS。在这台有问题的 PC 上,我们进行了映射和 GET。当我们尝试构建时,我们得到了一个错误,服务引用中使用的所有 List 类型都以某种方式被视为数组。我们在有问题的 PC 上安装了 VS 2010 并获得了该解决方案。同样的错误也存在。因此,它似乎与 VS 2012 无关。

所有电脑都是 Windows 7 专业版。

更多信息(2012 年 12 月 19 日添加):

项目打开时,本地PC上的ServiceReferences/ServiceReference1/Reference.cs被自动修改。变化是巨大的。以下是其中的一小部分:

显示了两种方法。 List get_Hotlines() 变成 string[] get_Hotlines() 和 List get_HotlinesBySite() 变成 string[] get_HotlinesBySite()。

为什么即使没有我的询问,文件也会被更改? VS 2012 升级日志说有两个文件被更改,但 Reference.cs 不是其中之一。

【问题讨论】:

我无法重现您的问题。您是否尝试使用适当的集合映射重新生成代理? 是的,我已经多次重新生成代理。我什至通过向同一个服务添加另一个具有不同名称 (ServiceReference2) 的服务来复制它。问题是一样的。在高级下,集合类型设置为 System.Collections.Generic.List。旁边的另一台 PC 具有完全相同的设置,但可以正常工作。 你确定它还在使用DataContractSerializer吗? (例如,生成的类是否具有 [DataContract] 属性?)也许它出于某种原因切换到 XmlSerializer,这不符合集合映射设置。 要清楚,您右键单击您的客户端项目并选择“添加服务引用”,并在高级选项中将集合类型设置为 System.Collections.Generic.List,对吗?您是否尝试过使用 svcutil.exe 生成代理?此外,“您旁边的 PC”是否为您所在的同一个 WCF 项目添加了相同的引用?配置一样吗? 所以我知道这是一个老问题,但这也是我遇到的问题。似乎当 svcutil.exe 遇到不知道如何序列化的东西时,所有的赌注都关闭了。 ***.com/questions/16657982/… 【参考方案1】:

当您添加对 wcf 服务的引用时,您需要将 Collection Type 更改为 Generic List:

您也可以更新此设置,只需在解决方案中选择服务引用,单击鼠标右键并选择“配置服务引用...”

【讨论】:

是的,这就是我一直在做的事情。正如我所解释的,尽管在 System.Collections.Gernic.List 中进行了此设置,但代理生成的方法都是在 Reference.cs 中看到的数组。首次在这台 PC 上打开项目时,会创建 Reference.cs 并包含 List 方法。但是每当我更新服务参考时,所有 List 方法都会变成数组方法。 您可以采用两种选择,因为涉及到 tfs。第一个选项是删除完整的 wcf 服务引用并使用正确的列表集合类型再次添加它。其次,转到放置参考文件的文件系统,选择所有文件并删除所有参考文件的只读标志,然后再次更新VS内部的参考。问题在于 tfs。 -1 OP 表示他已经这样做了。我也看到了同样的问题。它在同事的机器上生成列表,在我的机器上生成数组,即使我们在“服务参考设置”对话框中有相同的设置。【参考方案2】:

它为我做了什么:

    安装 Visual Studio 2013 的所有更新 取消选中“在引用的程序集中重用类型”

【讨论】:

【参考方案3】:

我在 VS2010 上遇到了同样的问题。经过数小时的尝试和测试,我认为这是代码生成的错误。我能够重现它。这是服务器端的代码,它会影响 Visual Studio 代码生成的行为。 在我的情况下,注释行产生了这个问题。当此成员不可为空时,Visual Studio 会生成 Array 集合而不是 List.

[DataContract]
public enum DocumentAttachmentSourceType

    [EnumMember]
    ServiceMission                              


[MessageContract]
public class DocumentUploadRequest : IDisposable

    [MessageHeader]
    public long NodeId  get; set; 

    [MessageHeader]
    public DocumentAttachmentSourceType? AttachmentSource  get; set;  //This works
    //public DocumentAttachmentSourceType  AttachmentSource  get; set;    //This not works !!!!!!!

    [MessageBodyMember]
    public System.IO.Stream Stream  get; set; 


    public void Dispose()
    
        if (Stream != null)
        
            Stream.Close();
            Stream = null;
        
     


【讨论】:

以上是关于WCF 代理返回数组而不是列表,即使集合类型 == Generic.List的主要内容,如果未能解决你的问题,请参考以下文章

返回零长度的数组或者集合,而不是null

生成的 WCF 代理为列表返回 null

Effective Java 之-----返回零长度的数组或集合而不是null

哪种列表/集合类型最适合在 WCF 数据协定中使用?

WCF 返回空的自定义集合类型

使用通道工厂而不是使用代理或添加服务引用来使用外部 WCF 服务