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

推荐订阅源

Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
J
Java Code Geeks
L
LangChain Blog
V
V2EX
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
Jina AI
Jina AI
Blog — PlanetScale
Blog — PlanetScale
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
博客园 - 司徒正美
B
Blog
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
Engineering at Meta
Engineering at Meta
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog

博客园 - JerryShi

使用流模式传输大型数据 对象序列化之 替换(Surrogate) 使用 IExtensibleDataObject 进行往返式序列化 使用 NetDataContractSerializer 共享类型 序列化 VS 编码 自定义 Behavior 操作行为 之 事务 服务行为 之 元数据 服务行为 之 并发与实例化 基本的WCF编程(实例) WCF Behaviors(行为) WCF 体系结构 WCF服务 使用netTcpBinding 无法打开默认数据库 SharePoint 创建SSP时出现找不到 Windows NT 用户或组 的异常 SQL Server 2008 Mirror 泛型(一) 自定义属性Attribute(三) 自定义属性Attribute(二)
WCF可序列化方式
JerryShi · 2011-10-22 · via 博客园 - JerryShi

WCF支持多种序列化方式,决定使用何种取决于多种因素,包括是否希望共享类型或契约,是否支持现有.net类型,是否保留引用等等。

DataContractSerializer

WCF中的默认序列化方式,其目的是对基于XSD schema契约进行共享,将CLR类型映射成XSD中定义的类型,XSD是应用程序间数据交换的协议。

如:使用XSD在 .NET与Java应用程序之间交换数据,以字符串为例:

XSD类型

DataContractSerializer Demo:展示如何使用DataContract,并获取实体类的Schema信息,使用DataContractSerializer序列化输出

实体类:

    [DataContract]
    public class Employee
    {
        [DataMember]
        public int EmployeeID { get; set; }

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

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

获取Schema:

public static void WriteSchema(Type type)
        {
            XsdDataContractExporter exporter = new XsdDataContractExporter();
            exporter.Options = new ExportOptions();
            exporter.Export(type);

            using (FileStream fs = new FileStream(string.Format("{0}/{1}.xsd", AppDomain.CurrentDomain.BaseDirectory, type.Name), FileMode.Create))
            {
                foreach (XmlSchema schema in exporter.Schemas.Schemas())
                {
                    schema.Write(fs);
                }
            }
        }

序列化输出:

public static void Serialize(object obj)
        {
            using (FileStream fs = new FileStream(string.Format("{0}/{1}.xml", AppDomain.CurrentDomain.BaseDirectory, obj.GetType().Name), FileMode.Create))
            {
                DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
                serializer.WriteObject(fs, obj);
            }
        }

Schema 数据:

<?xml version="1.0"?>
<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/JerryShi.EssentialWCF" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/JerryShi.EssentialWCF" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="Employee">
    <xs:sequence>
      <xs:element minOccurs="0" name="EmployeeID" type="xs:int" />
      <xs:element minOccurs="0" name="FirstName" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="LastName" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Employee" nillable="true" type="tns:Employee" />
</xs:schema>

序列化数据:

<Employee xmlns="http://schemas.datacontract.org/2004/07/JerryShi.EssentialWCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <EmployeeID>1</EmployeeID>
  <FirstName>Jerry</FirstName>
  <LastName>Shi</LastName>
</Employee>

NetDataContractSerializer

共享类型的序列化机制,如果在客户端与服务器之间,类型完全一致,则可以使用此序列化。 NetDatacontractSerializer 在序列化中保留了CLR类型和引用信息,支持类型不变性(type fidelity)。 除此之外NetDataContractSerializer 与 DataContractSerializer 没有区别。

对类型信息的共享,违背了只共享契约的原则,因此NetDataContractSerializer不适用于跨应用的系统,而适用于单一应用程序内部开发。

序列化代码:

public static void NetDataContractSerialize(object obj)
        {
            using (FileStream fs = new FileStream(string.Format("{0}/{1}_NetDataContractSerialize.xml", AppDomain.CurrentDomain.BaseDirectory, obj.GetType().Name), FileMode.Create))
            {
                NetDataContractSerializer serializer = new NetDataContractSerializer();
                serializer.WriteObject(fs, obj);
            }
        }

序列化数据:

<Employee z:Id="1" z:Type="JerryShi.EssentialWCF.Employee" z:Assembly="JerryShi.EssentialWCF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://schemas.datacontract.org/2004/07/JerryShi.EssentialWCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <EmployeeID>1</EmployeeID>
  <FirstName z:Id="2">Jerry</FirstName>
  <LastName z:Id="3">Shi</LastName>
</Employee>

NetDataContractSerializer 与 DataContractSerializer 比较:

1. 以自定义格式表示对象信息;

2. 包含对象Assmebly信息;

XmlSerializer

从.Net2.0起出现,支持现有.Net 类型,与ASP.NET Web Service兼容,能够控制XML输出结果

优势:  向前兼容、对序列化后的XML可以进行控制;。

使用XmlSerializer的三种方式:

1. 默认序列化方式,要求 构造方法必须为public,所有的public类型的字段及读写属性均会进行序列化;

2. 使用XmlElement和XmlAttribute特性,对public字段及读写属性进行标记,可以控制public字段和属性在xml中如何表示;

3. 使用IXmlSerializable接口来定制XmlSerializer的序列化,这种方法允许对序列化过程彻底的定制;

序列化数据:

<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <EmployeeID>1</EmployeeID>
  <FirstName>Jerry</FirstName>
  <LastName>Shi</LastName>
</Employee>

结果比较:与DataContractSerializer的结果很相似,最大的差异:XmlSerializer没有DataContractSerializer支持的类型多,但对Xml序列化数据有更多的控制能力。

特性:XmlSerializerFormat 可以用在服务契约、操作契约或服务上,用来指定WCF使用XmlSerializer 序列化方式。

在WCF契约中使用XmlSerializer 的方式,除了使用XmlSerializerFormat以外,也可以在使用svcutil.exe时使用参数: /serializer:xmlserializer 来生成以来XmlSerializer的代理代码。

DataContractJsonSerializer

从 .Net Framework 3.5 中出现,支持JavaScript对象序列化后的格式,适用于 Ajax、Silverlight 等应用。

当使用WebScriptEnablingBehavior行为 或 当WebHttpBehavior行为被配置成使用Json编码时,就会使用DataContractJsonSerializer。

DataContractJsonSerializer 遵循与DataContractSerializer一样的序列化规则,只是输出的格式是Json而不是Xml。

序列化数据:

{"EmployeeID":1,"FirstName":"Jerry","LastName":"Shi"}

选择序列化器

1. 如果需要支持现有类型或DataContractSerializer所不支持的序列化方式,应考虑XmlSerializer;

2. WCF 对NetDataContractSerializer没有直接支持,必须编写代码完成,不提倡使用;

3. DataContractJsonSerializer 主要用于Web 应用,Ajax或Silverlight