本帖介绍怎么在 WCF 中,在 Server-side 和 Client-side 之间,传递默认无法传输的 List
--------------------------------------------------------
本帖的示例下载点:
http://files.cnblogs.com/WizardWu/090809.zip
执行示例需要 Visual Studio 2008 + SP1,不需要数据库。
若您下载后,在 VS 2008 里按 F5 时项目无法正常执行,请留言告知。
--------------------------------------------------------
在编程时,DataSet、DataTable,以及 List、Dictionary 等 Collection 类型常会使用到。在 .NET Web Service 和 WCF 中,服务器端函数 (Operation) 的返回类型,若为 DataSet、DataTable,则客户端可直接调用 (若客户端程序也是 .NET 的话);但在 WCF 中,VS 2008 默认的配置,并无法传输 List
[注:Method、Operation 中文都叫做「方法」,但前者是存在 OO 中的类,不存在网络上;后者存在于 Service 中,公开在网络上可供其他程序调用。WCF、Data Services 和 RIA Services 中公开在网络上的函数和方法,都可称作 Operation。]
关于这点,小弟我查了微软 MCTS 认证 WCF 3.5 的官方用书 [10]、O'Reilly 的书籍 [11],都未提到如何解决,书中只提到 .NET collections 的 metadata,以 WSDL 在网络上传输时,会以「数组 (array)」的格式呈现。
Because .NET collections are .NET-specific, WCF cannot expose them in the service metadata, yet because they are so useful, WCF offers dedicated marshaling rules for collections.
Whenever you define a service operation that uses the collection interfaces IEnumerable
开发 WCF 时,若 VS 2008 都用默认配置,则当 WCF 的服务器端函数 (Operation) 的返回类型为 List
图 1 List 数据结构反序列化后,在客户端自动变成了数组
后来我在网络上发现两篇博文 [1], [2],提到只要更改 VS 2008 中,WCF 客户端程序「添加服务引用 (Add Service Reference)」的设置即可处理此种需求。做法如下:
请参阅本帖的下载示例。当我们的客户端程序,要引用网络上既有的 WCF 服务契约时,我们会如下图 2 般,添加一个 service proxy reference。
图 2 在 ASP.NET 客户端程序中引用 WCF Service
在下图 3 的「添加服务引用」窗体中,右上方的「前往」按钮,是要查看网络上某个 IP 和端口的 WCF Service;右边的「发现」按钮,是要查看和此客户端项目,位于同一个 VS 2008 解决方案里的 WCF Service。此时我们单击窗体左下方的「高级」按钮。
图 3 在此窗格里输入正确的元数据交换地址,会自动取得 WCF Service 的 Operation 名称
如下图 4,我们在「集合类型」下拉菜单中,把默认的 System.Array 改成我们想使用的 Generic.List 类型;而另一个「字典集合类型」下拉菜单则保持不变,表示此 WCF Service 可在网络上传输泛型的 Dictionary 类型对象。
图 4 默认的集合类型为 System.Array
微软的 VS 默认会这样设置,可能如同博文 [2] 所提到的,WCF 的客户端可能是旧版 .NET 1.x 版的环境,也可能是 Java 或其他各种非微软的技术平台,因此 VS 2008 默认选用所有厂商、所有平台都支持的 Array 数组,作为网络传输的类型,而非最新版 .NET 平台特有的 Collection 数据结构。
最后,若用户端程序要再更改配置,只要如下图 5 般,在 VS 项目里既有的 Reference 上,选择「配置服务引用」即可。
图 5 在 ASP.NET 客户端程序中,修改已引用的 WCF Service
以下为本帖下载示例的代码。我们在服务器端的 WCF Service,提供三个返回类型分别为 List
Client-side/Default.aspx.cs
{
protected void Page_Load( object sender, EventArgs e)
{
ServiceReference1.ServiceClient prox = new ServiceReference1.ServiceClient();
/* ********** List
// string[] list1 = new string[2]; // 未改设置前,Server 返回的 List
List < string > list1 = new List < string > ();
list1 = prox.getListString();
Response.Write(list1[ 0 ] + "
" );
Response.Write(list1[ 1 ] + " " );
/* ********** List<自定义类> ********** */
List < ServiceReference1.Employee > list2 = new List < ServiceReference1.Employee > ();
list2 = prox.getListEmployee();
Response.Write(list2[ 0 ].name + "
" );
Response.Write(list2[ 0 ].age + "
" );
Response.Write(list2[ 0 ].oooo + " " ); //object 类型
/* ********** Dictionary
Dictionary < string , string > dict1 = new Dictionary < string , string > ();
dict1 = prox.getDictionaryString();
foreach (KeyValuePair < string , string > kvp in dict1)
{
Response.Write(kvp.Key + " , " + kvp.Value + "
" );
}
}
}
图 6 本帖示例执行结果,从 WCF Service 返回 List
若有兴趣实作,但对 WCF 还不熟的网友,可参考下方参考文件 [8], [9],有提供快速入门的教学。
--------------------------------------------------------
相关文章:
[1] Using Generic List
http://dotnet.org.za/hiltong/archive/2008/05/21/using-generic-list-lt-t-gt-from-wcf-services.aspx
[2] WCF Data Contract对Collection和Dictionary的支持
http://www.cnblogs.com/artech/archive/2007/11/27/974665.html
[3] WCF分布式开发步步为赢(8):使用数据集(DataSet)、数据表(DataTable)、集合(Collection)传递数据
http://www.cnblogs.com/frank_xl/archive/2009/04/23/1437486.html
[4] WCF技术剖析之十三:序列化过程中的已知类型(Known Type)
http://www.cnblogs.com/artech/archive/2009/07/12/1521994.html
[5] Trouble getting a WCF return a collection to a .NET 2.0 client
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/3749248c-c3b0-40eb-88db-95574205dd9a
[6] Collection Types in Data Contracts
http://msdn.microsoft.com/zh-cn/library/aa347850.aspx
http://msdn.microsoft.com/en-us/library/aa347850.aspx
[7] Sharing WCF Collection Types between Service and Client
http://www.codeproject.com/KB/WCF/WCFCollectionTypeSharing.aspx
[8] Step-By-Step教學(10):將檔案類型 WCF 服務部署到 IIS (繁体中文, 与本帖无直接关系)
http://vmiv.blogspot.com/2008/05/step-by-step10wcfiis.html
[9] WCF学习----我的第一个WCF程序 (与本帖无直接关系)
http://www.cnblogs.com/ASPNET2008/archive/2008/06/01/1211613.html
--------------------------------------------------------
相关书籍:
[10] Microsoft .NET Framework 3.5-Windows Communication Foundation, MCTS EXAM 70-503 Training Kit, Chapter 1
http://www.microsoft.com/learning/en/us/Books/12486.aspx
http://www.amazon.com/MCTS-Self-Paced-Training-70-503-PRO-Certification/dp/0735625654
[11] Programming WCF Services, 2nd Edition, Juval Löwy, Chapter 3
WCF服务编程, Juval Löwy 着, 中文版本由「张逸、徐宁」翻译。
http://oreilly.com/catalog/9780596521301/
--------------------------------------------------------