03 数据契约_01 序列化

序列化

对象和本地引用属于CLR类(对象和类),而WCF基于XML样式。对象由操作它的状态和代码构成。无法将这些代码或逻辑作为C#或VB方法调用的一部分。
事实上,将对象(或值类型)作为操作参数进行传递时,真正需要发送的事对象的状态,然后接受端再将它转换为本地的表现形式。这种传递状态的方式成为值编组。如图所示。

这里写图片描述

.NET序列化

.NET通过反射技术自动实现了对象的序列化与反序列化。
.NET能够捕获对象的每个字段的值,并将它序列化到内存、文件或网络连接中。对于反序列化,.NET使用反射创建一个对应类型的新对象,读取它的持久化字段值,然后设置字段的值。由于反射能够访问私有字段,甚至包括字段基类的字段,因此,.NET在序列化期间能够完整地反射出对象的状态,从而保证了反序列化可以完整地重建对象状态。

序列化——Serialazable特性

如果,对象成员只有一些临时值或临时状态(如打开的数据库连接或者通信端口),对这样的对象状态执行了序列化,那么在反序列化时,根据流对的内容创建的对象就可能会存在缺陷。
在类或结构的定义添加SerialazableAttribute特性以支持序列化。

[Serialazable]
class MyClass{}

排除在序列化之外——NoSerialized特性

将成员变量排除在序列化之外——标记NoSerialized。

[Serialazable]
class MyClass{
    [NoSerialized]
    MyOtherClass m_otherClass;
}

.NET格式器

.NET类型的序列化和反序列化提供了两种格式器,且都实现了IFomatter接口

  • BinaryFormatter——将类型序列化为二进制格式,这种格式器能够快速地执行序列化和反序列化操作
  • SoapFormatter——使用了.NET特定的SOAP XML格式

除了要持久化对象的状态,两种格式器都要将类型的程序集以及版本控制信息持久化到流中,这样才能保证序列化的对象能够被反序列化为正确的类型。然而,这种呈现类型的方式却无法完全满足面向服务的交互,因为面向服务的交互方式要求其他的参与方不仅拥有类型程序集,还要使用.NET。由于它要求客户端和服务能够共享流,因此,使用流也不过是无奈之举。

WCF格式器

DataContractSerializer

DataContractSerializer能够共享数据契约,而不是基本的类型信息。
通过序列化或者数据契约样式,DataContractSerializer只能够捕获对象的状态。且DataContractSerializer没有实现IFomatter接口。

一般而言,WCF会自动地选择使用DataContractSerializer。然而可以使用DataContractSerializer实现类型与.NET流之间的序列化,但是不同于使用BinaryFormatter或SoapFormatter,需要为DataContractSerializer的构造函数提供它需要操作的类型,因为流里不会包含类型的信息。

扫描二维码关注公众号,回复: 3267890 查看本文章
MyClass obj1 = new MyClass( );
DataContractSerializer formatter = new DataContractSerializer(typeof(MyClass));
using(Stream stream = new MemoryStream( ))
{
formatter.WriteObject(stream,obj1);
stream.Seek(0,SeekOrigin.Begin);
MyClass obj2 = (MyClass)formatter.ReadObject(stream);
}

解决DataContractSerializer编译时类型安全问题
https://blog.csdn.net/Star_Inori/article/details/81088970

序列化的数据契约

当一个服务操作接收和返回任意类型或参数时,WCF会使用DataContractSerializer对参数进行序列化与反序列化。

参数或返回值传递给WCF的必要条件

  1. 使用自定义类型作为参数必须满足两个条件

    1. 类型必须是可序列化的
    2. 客户端和服务端必须是有相同数据架构的本地类型
  2. 客户端的类与WCF有可序列化的参数或者契约操作的返回值,如果两个对象是等效定义。那么就能将参数或者返回值传递给WCF。

基本类型在WCF中默认具有数据契约的特性,因为它们的样式都符合同一个行业标准。

等效定义——在序列化中能够生成相同数据样式的任何类型定义。

[Serializable]
struct Contact
{
public string FirstName;
public string LastName;
}
[Serializable]
struct Contact
{
public string FirstName;
public string LastName;
[NonSerialized]
public string Address;
}

猜你喜欢

转载自blog.csdn.net/Star_Inori/article/details/81072470