WCF-WCF中传输泛型List 对象(转)

摘自:http://www.cnblogs.com/homezzm/archive/2009/12/01/1614467.html

 

在编程时,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、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<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 数据结构反序列化后,在客户端自动变成了数组


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 默认会这样设置,可能如同博文所提到的,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  System.Collections.Generic;
using  System.ServiceModel;
using  System.Runtime.Serialization;

[ServiceContract]
[ServiceKnownType(
typeof (Employee))]
public  interface  IService
{
    [OperationContract]
    
string  GetData( int  value);

    [OperationContract]
    List
< string >  getListString();

    [OperationContract]
    [ServiceKnownType(
typeof (Employee))]
    List
< Employee >  getListEmployee();

    [OperationContract]
    Dictionary
< string string >  getDictionaryString();
}

[DataContract]
[KnownType(
typeof (Employee))]
public  class  Employee
{
    
public  Employee( string  name,  int  age,  object  oooo)
    {
        
this .name  =  name;
        
this .age  =  age;
        
this .oooo  =  oooo;
    }

    [DataMember]
    
public  string  name;
    [DataMember]
    
public  int  age;
    [DataMember]
    
public  object  oooo;
}
Server-side/Service.cs  System.Collections.Generic;
using  System.Runtime.Serialization;

public  class  Service : IService
{
    
public  string  GetData( int  value)
    {
        
return  string .Format( " You entered: {0} " , value);
    }

    
public  List < string >  getListString()
    {
        List
< string >  list1  =  new  List < string > ();
        list1.Add(
" List string 元素一 " );
        list1.Add(
" List string 元素二 " );
        
return  list1;
    }

    
public  List < Employee >  getListEmployee()
    {
        List
< Employee >  list2  =  new  List < Employee > ();
        list2.Add(
new  Employee( " 吴宇泽 " 18 new  object ()));
        list2.Add(
new  Employee( " 王大同 " 20 new  object ()));
        
return  list2;
    }

    
public  Dictionary < string string >  getDictionaryString()
    {
        Dictionary
< string string >  dict1  =    new  Dictionary < string string > ();
        dict1.Add(
" 吴宇泽 " " 程序员 " );
        dict1.Add(
" 王大同 " " 业务员 " );
        
return  dict1;
    }
}


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 三种类型的变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#,可以使用WCF(Windows Communication Foundation)来实现进程间通信。WCF是一种用于构建分布式应用程序的框架,它提供了一种灵活的方式来实现不同进程之间的通信。以下是实现WCF进程间通信的步骤: 1. 定义服务契约接口:在WCF服务,首先需要定义一个服务契约接口,该接口定义了服务的操作和数据契约。在服务契约接口,可以定义需要传递的数据和操作。 2. 实现服务契约接口:在WCF服务,需要实现定义的服务契约接口。在实现过程,可以使用回调方法来实现与客户端的通信。通过OperationContext的方法GetCallbackChannel()来获取回调对象,然后使用回调方法进行通信。 3. 配置WCF服务:在配置文件,需要定义WCF服务的终结点和绑定。终结点定义了服务的地址和协议,绑定定义了服务的通信方式和协议。 4. 创建WCF客户端:在客户端,需要创建一个WCF客户端对象,并指定服务的终结点和绑定。然后可以通过调用客户端对象的方法来与服务进行通信。 5. 调用WCF服务:在客户端,可以通过调用WCF客户端对象的方法来调用WCF服务。如果需要使用回调方法,可以在客户端实现回调契约的接口,并在服务端使用回调方法进行通信。 总结起来,使用WCF实现C#的进程间通信的步骤包括定义服务契约接口、实现服务契约接口、配置WCF服务、创建WCF客户端和调用WCF服务。通过这些步骤,可以实现不同进程之间的通信。[2][3]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值