惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

博客园 - windwolf

NHibernate的Decimal数据精度问题,急啊 最近M$发布了好多东东(我感兴趣的...) 对C#的一点抱怨 也谈WCF序列化(续) 开辟《WF本质论》专栏,以供同好探讨 petshop笔记 map,area标签 - windwolf - 博客园 Windows Workflow Foundation之旅(八)——使用活动控制流程、在工作流中使用条件 家里被洗劫。。。 Windows Workflow Foundation之旅(七)——顺序工作流、状态机工作流 Aspect#是怎么工作的? OO设计原则 Windows Workflow Foundation之旅(六)——框架组成、工作流创作模式 Windows Workflow Foundation之旅(五)——指南3(创建自定义活动) 微软中国最近的两个webcasts Windows workflow foundation之旅(四)——指南2(创建状态机工作流)(下) Windows workflow foundation之旅(三)——指南2(创建状态机工作流)(上) Windows Workflow Foundation之旅(二)——指南1(创建顺序工作流) Windows Workflow Foundation之旅(一)——概况
也谈WCF的序列化
windwolf · 2007-09-03 · via 博客园 - windwolf

逛园子时看到Artech兄的[原创]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I ,正好鄙人对WCF也略知一二,于是也来说两句~

大家知道,WCF内置了两种序列化方式,DataContractSerializer和NetDataContractSerializer。WCF的序列化的基本概念Artech兄已经说得很清楚了,在此不再赘述,本文仅就此二者的区别作一番探讨。

先来看看两者的声明:

public sealed class DataContractSerializer : XmlObjectSerializer
{
    
public DataContractSerializer(Type type);
   …
    
public override object ReadObject(XmlReader reader);

    
public object ReadObject(Stream stream);

    
public void WriteObject(Stream stream, object graph);

    
public override void WriteObject(XmlWriter writer, object graph);

    … 

}
 

public sealed class NetDataContractSerializer : XmlObjectSerializer, IFormatter
{
    
public NetDataContractSerializer();

   …
    
public object Deserialize(Stream stream);
    
public void Serialize(Stream stream, object graph);

    
public override object ReadObject(XmlReader reader);
    
public object ReadObject(Stream stream);
    
public void WriteObject(Stream stream, object graph);
    
public override void WriteObject(XmlWriter writer, object graph);
   …

}


其中两者的ReadObject(Straem)、WriteObject(Stream, object)的实现继承自基类XmlObjectSerializer,其他方法均为已覆写或实现。

从两个类型的声明中可以看出NetDataContractSerializer实现了IFormatter接口,而DataContractSerializer没有,因此只有NetDataContractSerializer能使用.NET基础结构中的序列化,而DataContractSerializer则是专用于WCF的。

还有一个细节DataContractSerializer的Constructor有一个Type类型的参数,而NetDataContractSerializer没有。这可蕴藏着深意啊,读者接着看就明白了。

现在,再来看看此二者的最大关键区别吧!从一个示例开始吧:

[DataContract]
public class Sub        
{
   
// Fields
   [DataMember]
    
public int Id;

   [DataMember]
   
public string Name;

   
// Methods
   public Sub()
   
{}

   
public Sub(int id, string name)
   
{
      
this.Id = id;
      
this.Name = name;
   }


}


以上是一个再简单不过的DataContract的,把他给序列化看看出来些啥。
先用DataContractSerializer序列化:

Sub sub = new Sub(9"nine");

DataContractSerializer dcs 
= new DataContractSerializer(typeof(Sub));

MemoryStream stream 
= new MemoryStream();
dcs.WriteObject(stream, sub);
byte[] buf = stream.ToArray();
string str = Encoding.UTF8.GetString(buf, 0, buf.Length);

执行完以上代码后,str的值为:

<Sub xmlns="http://schemas.datacontract.org/2004/07/ServiceInterface" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
  
<Id>10</Id> 
  
<Name>nine</Name> 
</Sub>

恩,此SOAP消息那是相当得正常。然后将同一个对象用NetDataContractSerializer序列化:

   NetDataContractSerializer ndcs = new NetDataContractSerializer();
   MemoryStream nstream 
= new MemoryStream();
   ndcs.WriteObject(nstream, sub);
   
byte[] nbuf = nstream.ToArray();
   
string nstr = Encoding.UTF8.GetString(nbuf, 0, nbuf.Length);

观察一下nstr的值:



<Sub z:Id="1" z:Type="ServiceInterface.Sub" z:Assembly="ServiceInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://schemas.datacontract.org/2004/07/ServiceInterface" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"> 
  
<Id>10</Id> 
  
<Name z:Id="2">nine</Name> 
</Sub> 


发现了吗?撇开xml命名空间不说,Sub元素多了Type,Assembly和Id,Name属性也多了个Id。信息完整多了~~,现在就可以解释两者Constructor的区别了,DataContractSerializer是按照SOA的datacontract协议(与SOAP基本一直)来序列化对象的,它并不包含平台相关的信息,比如类型,程序集等。所以比如在创建序列化器时就提供将要序列化和反系列化的类型信息,DataContractSerializer无法工作。而NetDataContractSerializer则大大扩充了SOAP,为它添加了程序集、类型名等附加信息,这样一来,序列化器可以完全由序列化的内容来准确推断将要构造的对象,而不必依赖Constructor所提供的类型参数了。这就是两者Constructor不同的原因。

那么z:Id是做什么的呢?嘿嘿,请看下回分解~

下篇链接