您的位置:首页 > 其它

WCF基础教程(四)——数据契约实现传送自定义数据类型

2015-11-10 11:50 691 查看
   

   引言

   将近两个月的时间都在准备软考和项目上的一些事情,对于这个教程的更新没有跟上,从今天开始我会继续更

新这个教程,今天上午花费了一定的时间来看看了前面的几篇博客,在这篇博客会根据在第一篇博客讲解的实例,进

行更新,如何从客户端和服务端之间传送自定类型的数据,之前的实例中都是传送的常规类型,像string int等等。

首先在给大家介绍一个契约——数据契约。

  数据契约

  在第一个实例中我们接触到了服务契约——用来描述了暴露给外部类型(接口、类)、服务所支持的操作、使用

消息交换模式和信息的格式。每个WCF服务都必须实现一个服务契约。

 而数据契约和服务契约差不多的作用,用在在服务端和客户端之间传送定义好的数据类型,在使用数据契约的时候

必须引用:System.Runtime.Serialization;在类型上使用DataContracAttribute可以创建数据契约,在类型中使用

成员使用DataMember标记,基本代码如下:

[Dataontract]
public class userEntity

{
[DataMember]
public string name { get; set; }
}


   三个关键字   

   DataContractAttribute特性定义在类型之上,类型包括类、结构、枚举但不包括接口。

DataContractAttribute特性不能被继承,即继承自有DataContractAttribute特性标记的类并不是数据契约,必须显

示使用DataContractAttribute标记才能成为数据契约。DataContractAttribute特性有IsReference、Name和

Namespace三个属性:

   1、IsReference:bool类型,表示在进行序列化的时候是否保持对象现有的引用结构。

   2、Name:名称。

   3、Namespace:命名空间。

[DataContract(IsReference=true,Name="MyUser",Namespace="http://oec2003.cnblogs.com")]
public class User
{
[DataMember]
public int Age { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
}
</pre><h5 style="line-height:26px"></h5><h2 style="line-height:26px; background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"> </span><span style="font-family:SimSun"><span style="font-size:18px">  DataMemberAttribute</span></span></h2><div><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal"></span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal">   使用DataMemberAttribute标记的类型成员才能成为数据契约的数据成员。这个和服务契约中的</span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal"></span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal">OperationContractAttribute类似。DataMemberAttribute特性有如下四个属性:</span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-weight:normal; font-family:SimSun; font-size:18px">   1、EmitDefaultValue:表明在数据成员的值等于默认值的情况下,是否还须要将其序列化到最终的XML中,默认</span></div><div style="background-color:rgb(255,255,255)"><span style="font-weight:normal; font-family:SimSun; font-size:18px"></span></div><div style="background-color:rgb(255,255,255)"><span style="font-weight:normal; font-family:SimSun; font-size:18px">值为</span><span style="font-family:SimSun; font-size:18px; font-weight:normal">true,表示默认值会参与序列化。</span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal"></span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal">   2、IsRequired:bool类型,表明属性成员是否是必须的成员,默认值为false。</span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal">   3、Name:数据成员的别名。</span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal">   4、Order:相应的数据成员在最终序列化的XML中出现的位置,默认是按字母顺序排列的。</span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal"></span></span></div><div style="background-color:rgb(255,255,255)"><span style="font-family:SimSun; font-size:18px"><span style="font-weight:normal"></span></span><pre name="code" class="csharp">[DataContract(IsReference=true,Name="MyUser",Namespace="http://oec2003.cnblogs.com")]
public class User
{
[DataMember(EmitDefaultValue=true,IsRequired=true,
Name="Oec2003_Age",Order=1)]
public int Age { get; set; }
[DataMember(EmitDefaultValue = true, IsRequired = true,
Name = "Oec2003_Name", Order = 2)]
public string Name { get; set; }
[DataMember(EmitDefaultValue = true, IsRequired = false,
Name = "Oec2003_Email", Order = 3)]
public string Email { get; set; }

使用数据契约的注意事项

在这里大家需要注意一点就是数据契约和服务契约的一点区别:数据契约要求在客户端和服务端必须保持完全一
致的类名与命名空间,否则就无法传递数据,这与服务契约是不同的,服务契约放到客户端时允许换个命名空间。
我在学习的时候将原先传送string类型的数据改为传送实体类类型后就不能读出数据,原因是在客户端和服务端
的命名空间不一样,我们需要构造一个一致的命名空间,代码如下:
客户端代码:
<span style="font-weight: normal; background-color: rgb(255, 255, 255);">using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Web;

namespace DemoClientWCF
{
</span><span style="background-color: rgb(255, 0, 0);">[DataContract(Namespace = "zhenghao")]</span><span style="font-weight: normal; background-color: rgb(255, 255, 255);">

[Serializable]
public class userEntity
{
[DataMember]
public string name { get; set; }
}
}</span>

protected void btnClick(object sender, EventArgs e)
{
UserClient user = new UserClient();

userEntity name = new userEntity();
name.name = this.txtName.Text;
string result = user.ShowName(name);
Response.Write(result);
}

服务端代码如下
<span style="background-color: rgb(255, 255, 255);">namespace DemoServiceWCF
{
</span><span style="color:#333333;background-color: rgb(255, 0, 0);">[DataContract(Namespace="zhenghao")]</span><span style="background-color: rgb(255, 255, 255);">

[Serializable]
public class userEntity

{
[DataMember]
public string name { get; set; }
}
}</span>

public class User : IUser
{

public string ShowName(userEntity name)
{
string wcfName = string.Format("WCF服务,显示姓名:{0}", name.name);
return wcfName;
}

}

其余代码和第一篇博客中的代码一样,图中标红的代码就是给客户端和服务端定义了一个一样的命名空间,这样就
能完成传送自定义类型的数据了。

小结

通过对数据契约的学习,我们就可以实现了客户端和服务端传送自定义类型数据的问题,这些在WCF的学习中比较
基础的知识,但是非常的重要,因为如果我们不能很好的理解这其中的原理,在程序出现错误的时候我们就无从下
手,所以对于WCF的基础知识的学习,我会继续和大家分享!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: