博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WCF传输泛型 List 对象 转
阅读量:6234 次
发布时间:2019-06-22

本文共 4770 字,大约阅读时间需要 15 分钟。

http://www.cnblogs.com/WizardWu/archive/2009/08/09/1542102.html

 

在 WCF 中,在 Server-side 和 Client-side 之间,传递默认无法传输的 List<T>、List<自定义类> 等类型的对象,以及传递 Dictionary 等泛型 Collection 对象。本帖并无高来高去的高深技术,但版工我认为本帖的小技巧实用性很高,而且是每个学习 WCF 的人都一定会遇到的问题,因此斗胆将本文发在博客园首页。

--------------------------------------------------------

本帖的示例下载点:

执行示例需要 Visual Studio 2008 + SP1,不需要数据库。

若您下载后,在 VS 2008 里按 F5 时项目无法正常执行,请留言告知。
--------------------------------------------------------

在编程时,DataSet、DataTable,以及 List、Dictionary 等 Collection 类型常会使用到。在 .NET Web Service 和 WCF 中,服务器端函数 (Operation) 的返回类型,若为 DataSet、DataTable,则客户端可直接调用 (若客户端程序也是 .NET 的话);但在 WCF 中,VS 2008 默认的配置,并无法传输 List<string>、List<自定义类> 等类型的对象,而泛型的 Dictionary 对象却可以。

[注:Method、Operation 中文都叫做「方法」,但前者是存在 OO 中的类,不存在网络上;后者存在于 Service 中,公开在网络上可供其他程序调用。WCF、 和 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<T>, IList<T>, or ICollection<T>, the specific collection-type information gets lost in the metadata (WSDL) export, so in terms of how collection types are sent across the wire, they all are represented as arrays, the resulting metadata always uses an array.

 

开发 WCF 时,若 VS 2008 都用默认配置,则当 WCF 的服务器端函数 (Operation) 的返回类型为 List<string> 时,实际返回的类型为 string[] 数组,因此客户端若仍用 List<string> 的变量去接收和赋值时,在编译时期,即会发生下图 1 的转型错误:

图 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<string>、List<自定义类>、Dictionary<string,string> 的函数,给 WCF 客户端 ASP.NET 程序调用,执行结果如下图 6。

 

Server-side/IService.cs

 

 

Server-side/Service.cs

 

Client-side/Default.aspx.cs

public
 
partial
 
class
 _Default : System.Web.UI.Page 
{
    
protected
 
void
 Page_Load(
object
 sender, EventArgs e)
    {
        ServiceReference1.ServiceClient prox 
=
 
new
 ServiceReference1.ServiceClient();
        
/*
********** List<string> **********
*/
        
//
string[] list1 = new string[2];   
//
未改设置前,Server 返回的 List<string>,Client 只能取得 string 数组
        List
<
string
>
 list1 
=
 
new
 List
<
string
>
();        
        list1 
=
 prox.getListString();
        Response.Write(list1[
0
+
 
"
<br>
"
);
        Response.Write(list1[
1
+
 
"
<p>
"
);
        
/*
********** List<自定义类> **********
*/
        List
<
ServiceReference1.Employee
>
 list2 
=
 
new
 List
<
ServiceReference1.Employee
>
();
        list2 
=
 prox.getListEmployee();
        
        Response.Write(list2[
0
].name 
+
 
"
<br>
"
);
        Response.Write(list2[
0
].age 
+
 
"
<br>
"
);
        Response.Write(list2[
0
].oooo 
+
 
"
<p>
"
);      //object 类型
        
/*
********** Dictionary<string,string> **********
*/
        Dictionary
<
string
string
>
 dict1 
=
 
new
 Dictionary
<
string
string
>
();
        dict1 
=
 prox.getDictionaryString();
        
foreach
 (KeyValuePair
<
string
string
>
 kvp 
in
 dict1)
        {
            Response.Write(kvp.Key 
+
 
"
"
 
+
 kvp.Value 
+
 
"
<br>
"
);
        }
    }
}
复制代码

 

 

图 6 本帖示例执行结果,从 WCF Service 返回 List<string>、List<自定义类>、泛型 Dictionary 三种类型的变量

 

若有兴趣实作,但对 WCF 还不熟的网友,可参考下方参考文件 [8], [9],有提供快速入门的教学。

--------------------------------------------------------

相关文章:

[1] Using Generic List<T> From WCF Services

[2] WCF Data Contract对Collection和Dictionary的支持

[3] WCF分布式开发步步为赢(8):使用数据集(DataSet)、数据表(DataTable)、集合(Collection)传递数据

[4] WCF技术剖析之十三:序列化过程中的已知类型(Known Type)

[5] Trouble getting a WCF return a collection to a .NET 2.0 client

[6] Collection Types in Data Contracts

[7] Sharing WCF Collection Types between Service and Client

[8] Step-By-Step教學(10):將檔案類型 WCF 服務部署到 IIS (繁体中文, 与本帖无直接关系)

[9] WCF学习----我的第一个WCF程序 (与本帖无直接关系)

--------------------------------------------------------

相关书籍:

[10] Microsoft .NET Framework 3.5-Windows Communication Foundation, MCTS EXAM 70-503 Training Kit, Chapter 1

[11] Programming WCF Services, 2nd Edition, Juval Löwy, Chapter 3

WCF服务编程, Juval Löwy 着, 中文版本由「张逸、徐宁」翻译。

--------------------------------------------------------

你可能感兴趣的文章
假如有一天,人工智能用于相亲
查看>>
0227 - 简单了解了 ETH 挖矿
查看>>
技术问答集锦(14)ThreadPoolExecutor
查看>>
macOS Charles 4.x版本的安装及使用(含破解激活)
查看>>
InnoDB透明页压缩与稀疏文件
查看>>
阅读SSM项目之scm【第二篇】
查看>>
聊聊springmvc中controller的方法的参数注解
查看>>
AspectJ 学习笔记
查看>>
GRU神经网络
查看>>
【log4】window用于设置小程序的状态栏、导航条、标题、窗口背景色。
查看>>
gpexpand分析
查看>>
前端每周清单第 44 期: 2017 JS 调查报告、REST 接口实时化、ESM 的过去与未来
查看>>
IP、UDP初探
查看>>
分布式系统中常见技术解决的问题是什么?
查看>>
WWDC 2018:理解崩溃以及崩溃日志
查看>>
「 iOS知识小集 」2018 · 第 40 期
查看>>
太极越狱重大安全后门
查看>>
一步一步学ROP之linux_x86篇
查看>>
【译】Ruby2.6的JIT功能,编译和解释型语言的相关说明
查看>>
架构设计知识梳理(2) Flux
查看>>