数据协定等效性特点概述

  • 对于客户端要将某种类型的数据成功发送到服务,或者服务要将数据成功发送到客户端的情况,接收端上并不一定必须存在此发送数据类型。 唯一的要求是两种类型的数据协定应该等效。
  • 要使数据协定等效,其命名空间和名称必须相同。 此外,某一端上的每个数据成员还必须在另一端上具有等效的数据成员。注意,数据协定名称和命名空间以及数据成员名称均区分大小写。
  • 要使数据成员等效,其名称必须相同。 此外,它们还必须表示同一类型的数据,也就是说,其数据协定必须等效。
  • 如果同一端(发送方或接收方)存在两种类型,而其数据协定又不等效(例如,它们的数据成员不同),则不应为它们指定相同的名称和命名空间。 否则,可能会引发异常。
  • 使用 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. javascript jsscript .js xml html json soap

    javascript ecma标准的脚本语言用于 jsscript 微软标准的一种脚本语言 .js javascript或jsscript保存成文件的形式可用于在html里重复引用 jsscript只 ...

  2. AJAX-----06XMLHttpRequest对象的处理返回的XML类型数据

    我们首先要确保XML文件是否正常执行 如果访问时候报类似  Parse error: syntax error, unexpected 'version' (T_STRING  这样的错误,我们则需要 ...

  3. PHP二维数组提取函数----把不需要的数据剔除

    首先说明一些这个函数的应用场景,比如说你得到的数据是个二维数组,里面的很多成员其实是不必要的,比如说api调用后不必要给别人返回一些用不到的垃圾数据吧,如下是代码. <?php /* * del ...

  4. Gym 100500B

    题目给了四个轮子,每个轮子上有按顺序排列的n个数,要求适当旋转每个轮子,使得四个轮子相同行数相加和相同. 首先,可以计算出每一行的和应该是多少,记为Sum.然后固定第一个轮子,二重循环枚举2.3轮子, ...

  5. Hide SSH Welcome Banner/Message on Ubuntu14.04+

    Introduction Usually when you logged in you linux based PC remotely via SSH, a long banner will be d ...

  6. postgresql命令行

    原文链接 PostgreSQL 8.1 中文文档 连接数据库, 默认的用户和数据库是postgrespsql -U user -d dbname \c dbname 切换数据库,相当于mysql的us ...

  7. 打包app命令行

    $ cd myApp $ ionic platform add android $ ionic build android $ ionic emulate android

  8. String s ; 和 String s = null ; 和 String s = "" ; 的却别

    String s ;该语句表示只是声明了一个引用变量,但是并没有初始化引用,所以对变量s的任何操作(除了初始化赋值外) 都将引发异常. String s=null; 表示未申请任何内存资源,即此语句表 ...

  9. 【转】SVN的dump文件导入

    转载地址:http://erniu.sz.blog.163.com/blog/static/11517292220103282813176/ 把SVN的dump文件导入SVN数据库的方法: 在SVN ...

  10. apache和tomcat有什么不同,为什么要整合apache 和tomcat?

    1. Apache是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展.2. Apache和Tomcat都可以做为独立的web服务器来运行,但是Ap ...