数据协定等效性特点概述

  • 对于客户端要将某种类型的数据成功发送到服务,或者服务要将数据成功发送到客户端的情况,接收端上并不一定必须存在此发送数据类型。 唯一的要求是两种类型的数据协定应该等效。
  • 要使数据协定等效,其命名空间和名称必须相同。 此外,某一端上的每个数据成员还必须在另一端上具有等效的数据成员。注意,数据协定名称和命名空间以及数据成员名称均区分大小写。
  • 要使数据成员等效,其名称必须相同。 此外,它们还必须表示同一类型的数据,也就是说,其数据协定必须等效。
  • 如果同一端(发送方或接收方)存在两种类型,而其数据协定又不等效(例如,它们的数据成员不同),则不应为它们指定相同的名称和命名空间。 否则,可能会引发异常。
  • 使用 DataMemberAttribute 类的 Order 属性可能会影响数据协定等效性。 其成员必须以相同顺序出现,数据协定才能等效。

数据协定等效性说明

 

   

  • 在上图中,我们在服务端定义了数据协定为User和Person的类,他们在客户端都会生成和标记3一样的客户端数据契约类型。因此,我们称User和Person是具有等效性的数据契约。
  • 数据协定的等效性要求只与上面的数据协定等效性特点概述有关,与数据协定本身的类定义无关。也就是说,只要在服务端定义的数据契约类型在客户端代理类中生成相同的数据契约,我们就称服务端的这些数据协定具有等效性。
  • 有了上述特点,我们就可以在服务端任意替换具有等效性的数据协定,而不必修改和重新生成客户端,客户端都能正常运行

数据协定等效性示例

  • 解决方案如下:

  

  • 工程结构说明
  1. Service:类库类型,WCF服务端程序。IUserInfo.cs代码如下:
  

using System.ServiceModel;
using System.Runtime.Serialization; namespace Service
{
[ServiceContract]
public interface IUserInfo
{
[OperationContract]
User[] GetInfo();
} [DataContract]
public class User
{
[DataMember]
public int ID { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public int Age { get; set; } [DataMember]
public string Nationality { get; set; }
}
}

    UserInfo.cs代码如下: 

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Service
{
public class UserInfo:IUserInfo
{
public User[] GetInfo()
{
List<User> Users = new List<User>();
Users.Add(new User { ID = , Name = "JACK", Age = , Nationality = "CHINA" });
Users.Add(new User { ID = , Name = "TOM", Age = , Nationality = "JAPAN" });
Users.Add(new User { ID = , Name = "SMITH", Age = , Nationality = "KOREA" });
Users.Add(new User { ID = , Name = "ALENCE", Age = , Nationality = "INDIA" });
Users.Add(new User { ID = , Name = "JOHN", Age = , Nationality = "SINGAPORE" }); return Users.ToArray();
}
}
}

  2.  Host:控制台应用程序,WCF服务承载程序。添加对Service程序集的引用,完成以下代码和配置后就可以寄宿服务。Program.cs的代码如下:

  

using System;
using System.ServiceModel;
using Service; namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(UserInfo)))
{
host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };
host.Open();
Console.Read();
}
}
}
}

  App.config的代码如下:

  

<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.UserInfo" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/UserInfo/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="Service.IUserInfo" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

  我们通过svcutil.exe工具生成客户端代理类和客户端的配置文件

  svcutil.exe是一个命令行工具,位于路径C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin下,我们可以通过命令行运行该工具生成客户端代理类

  • 在运行中输入cmd打开命令行,输入 cd C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
  • 输入svcutil.exe /out:f:\UserInfoClient.cs /config:f:\App.config http://localhost:1234/UserInfo

  3.  Client:控制台应用程序,客户端调用程序。将生成的UserInfoClient.cs和App.config复制到Client的工程目录下,完成客户端调用代码。Program.cs的代码如下:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service; namespace Client
{
class Program
{
static void Main(string[] args)
{
UserInfoClient proxy = new UserInfoClient();
User[] Users = proxy.GetInfo();
Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "ID", "Name", "Age", "Nationality");
for (int i = ; i < Users.Length; i++)
{
Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}",
Users[i].ID.ToString(),
Users[i].Name.ToString(),
Users[i].Age.ToString(),
Users[i].Nationality.ToString());
} Console.Read();
}
}
}

  4.  程序运行效果如下:

  

数据协定等效性验证

  • 接下来,我们修改服务端的数据协定,并且修改操作协定的实现代码。IUserInfo.cs的代码如下:
using System.ServiceModel;
using System.Runtime.Serialization; namespace Service
{
[ServiceContract]
public interface IUserInfo
{
[OperationContract]
Person[] GetInfo();
} [DataContract(Name = "User")]
public class Person
{
[DataMember]
public int ID { get; set; } [DataMember(Name = "Name")]
public string 姓名 { get; set; } [DataMember]
public int Age { get; set; } [DataMember]
public string Nationality { get; set; }
}
}

  UserInfo.cs的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Service
{
public class UserInfo:IUserInfo
{
public Person[] GetInfo()
{
List<Person> Persons = new List<Person>();
Persons.Add(new Person { ID = , 姓名 = "JACK", Age = , Nationality = "CHINA" });
Persons.Add(new Person { ID = , 姓名 = "TOM", Age = , Nationality = "JAPAN" });
Persons.Add(new Person { ID = , 姓名 = "SMITH", Age = , Nationality = "KOREA" });
Persons.Add(new Person { ID = , 姓名 = "ALENCE", Age = , Nationality = "INDIA" });
Persons.Add(new Person { ID = , 姓名 = "JOHN", Age = , Nationality = "SINGAPORE" }); return Persons.ToArray();
}
}
}
  • 修改后我们保存并重新生成Host程序,Client程序不做任何操作。运行结果和先前一样,说明两次定义的数据协定时等效的。程序运行效果如下:

  

  • 接下来,我们再次修改数据协定,为数据协定的成员添加Order属性,修改代码如下所示,修改后我们重新编译Host,运行程序。运行后我们发现程序没有报错。但是ID和Age的值都变成了0,说明契约的等效性受Order的影响。
    [DataContract(Name = "User")]
public class Person
{
[DataMember(Order = )]
public int ID { get; set; } [DataMember(Name = "Name")]
public string 姓名 { get; set; } [DataMember(Order = )]
public int Age { get; set; } [DataMember(Order = )]
public string Nationality { get; set; }
}

  

WCF初探-17:WCF数据协定之等效性的更多相关文章

  1. WCF技术剖析之十六:数据契约的等效性和版本控制

    原文:WCF技术剖析之十六:数据契约的等效性和版本控制 数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据.在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交 ...

  2. 我们一起学习WCF 第五篇数据协定和消息协定

    A:数据协定(“数据协定”是在服务与客户端之间达成的正式协议,用于以抽象方式描述要交换的数据. 也就是说,为了进行通信,客户端和服务不必共享相同的类型,而只需共享相同的数据协定. 数据协定为每个参数或 ...

  3. WCF学习心得------(六)数据协定

    --前言 最近各种事忙的把之前的WCF学习给耽误了一些,今天抽时间把之前的学习内容给总结了一下,因为知识点比较细碎没有做太多的练习示例,只是对其中关键的知识点做了总结,希望可以对大家有所帮助. 第六章 ...

  4. WCF基础之数据协定

    数据协定最重要的当然就是DataContract和DataMember.这两个特性能应用到类.结构和枚举.这个两个特性跟服务契约的特点是一样的,只有被DataContract标记的类和类中被标记Dat ...

  5. WCF初探文章列表

    WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...

  6. WCF初探-16:WCF数据协定之基础知识

    数据协定概念 “数据协定”是在服务与客户端之间达成的正式协议,用于以抽象方式描述要交换的数据. 也就是说,为了进行通信,客户端和服务不必共享相同的类型,而只需共享相同的数据协定. 数据协定为每一个做数 ...

  7. WCF初探-18:WCF数据协定之KnownType

    KnownTypeAttribute 类概述 在数据到达接收终结点时,WCF 运行库尝试将数据反序列化为公共语言运行库 (CLR) 类型的实例.通过首先检查传入消息选择为反序列化而实例化的类型,以确定 ...

  8. WCF初探-14:WCF服务协定

    前言: 在前面的文章中,我们定义的服务协定上都会有一个ServiceContract的特性来修饰,这是因为服务契约的实现要靠ServiceContractAttribute 属性定义,然后使用一个或多 ...

  9. WCF初探-20:WCF错误协定

    WCF错误协定概述 在所有托管应用程序中,处理错误由 Exception 对象表示. 在基于 SOAP 的应用程序(如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息. SO ...

随机推荐

  1. 获取乌云补天指定关键字的漏洞并输出URL和标题

    #coding=utf-8 import urllib2 import re import time def timestamp():         return str(time.strftime ...

  2. ef第一次启动较慢

    解决ef第一次启动较慢的问题: protected void Application_Start() { //禁用第一次ef查询对表__MigrationHistory的问题使用了ef的Code fi ...

  3. struts 数据验证

    1. validate()验证 将对页面表单验证的内容写到validate()方法中,实现验证和业务处理内容的分离 在Action中添加 validate()方法   public void vali ...

  4. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数008,matrix,矩阵函数

    ** 3dFromFundamentalMatrix( Rows1, Cols1, Rows2, Cols2, CovRR1, CovRC1, CovCC1, CovRR2, CovRC2, CovC ...

  5. C#中把Datatable转换为Json的5个代码实例

    一. /// <summary> /// Datatable转换为Json /// </summary> /// <param name="table" ...

  6. POJ - 1245 Programmer, Rank Thyself

    POJ - 1245 Programmer, Rank Thyself Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d  ...

  7. 编译libjpeg库

    最近在写车牌识别软件,需要用到BMP转成JPG的功能,自然就想到借助libjpeg来实现 OS: win7 64位 编译器: VS2008 1. 下载源代码下载地址:http://www.ijg.or ...

  8. opensuse-13.1体验

    1  livecd安装 下载地址 http://software.opensuse.org/131/zh_CN 我下载的kde版本的livecd,不像ubuntu支持ultraiso的U盘安装,也不支 ...

  9. MySQL配置文件mysql.ini参数详解

    my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数. my.ini分为两块:Client Section和Server Section. ...

  10. [转]error: 'retainCount' is unavailable: not available in automatic reference counting mode

    转载地址:http://choijing.iteye.com/blog/1860761   后来发现是编译选项的问题:   1.点击工程名 打开编译选项 2.在编译选项中,选择Bulid Settin ...