您的位置:知识库 » .NET技术

WCF分布式开发步步为赢(7):WCF数据契约与序列化

作者: Frank Xu Lei  来源: 博客园  发布时间: 2009-06-01 10:43  阅读: 7736 次  推荐: 0   原文链接   [收藏]  
摘要:WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤。
[1] 数据契约
[2] 序列化基本概念
[3] .NET 序列化机制
[4] 代码实现与分析

  【2】.NET 序列化机制:

  .net的序列化。.net是通过反射机制自动实现对象的序列化与反序列化。首先.net能够捕获对象每个字段的值,然后进行序列化,反序列化时,.net创建一个对应类型的新的对象,读取持久化的值,然后设置字段的值。.net对象状态的序列化到Stream中。.NET Framework 提供三种序列化技术:

  1.BinaryFormatter二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等等。远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象。

     2.调用System.Runtime.Serialization.Formatters.Soap空间下的SoapFormatter类进行序列化和反序列化,序列化之后的文件是Soap格式的文件(简单对象访问协议(Simple Object Access Protocol,SOAP),WCF分布式开发必备知识(4):Web Service也进行了介绍,SOAP是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。 SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象。可以实现跨平台数据的交互。

  3.XML 序列化需要引用System.Xml.Serialization,使用XmlSerialize类进行序列化和反序列化操作。它仅序列化公共属性和字段,且不保持类型保真度。基于XML 标准,支持跨平台数据交互。

    BinaryFormatter二进制序列化的优点:1. 所有的类成员(包括只读的)都可以被序列化;2. 性能高。

    SoapFormatter、XmlSerialize的优点:1. 跨平台,互操作性好;2. 不依赖二进制;3. 可读性强。

    当然.NET原有的序列化器也有自己的局限性,因为他们除了要序列化对象的状态信息外,还要将程序集的信息和版本信息持久化到流中,这样才能保证对象被反序列化为正确的对象类型副本。这要求客户端必须拥有使用.NET程序集。不能满足跨平台的WCF数据交互的需求。

  【3】WCF序列化机制:

  由于.NET格式化器固有的缺陷,WCF不得不提供自己的格式化,以满足其面向服务的需求。在WCF程序集里,提供了专门用户序列化和反序列化操作的类:DataContractSerializer,在System.Runtime.Serialization命名空间里。使用Reflector查看其定义信息如下:

public abstract class XmlObjectSerializer
{
    
// Methods
    protected XmlObjectSerializer()
    {
    }
    
internal static void CheckNull(object obj, string name)
    {
        
if (obj == null)
        {
            
throw new ArgumentNullException(name);
        }
    }
    
internal virtual Type GetSerializeType(object graph)
    {
        
if (graph != null)
        {
            
return graph.GetType();
        }
        
return null;
    }
    
private static string GetTypeInfoError(int errorMessage, Type type, Exception
innerException)
    {
        
string str = (type == null? string.Empty : SR.GetString(1new object[]
{ DataContract.GetClrTypeFullName(type) });
        
string str2 = (innerException == null? string.Empty : innerException.Message;
        
return SR.GetString(errorMessage, new object[] { str, str2 });
    }

    
public abstract bool IsStartObject(XmlDictionaryReader reader);
    
public virtual bool IsStartObject(XmlReader reader)
    {
        CheckNull(reader, 
"reader");
        
return this.IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader));
    }

    
public virtual object ReadObject(XmlDictionaryReader reader)
    {
        
return this.ReadObject(reader, true);
    }
    
public virtual object ReadObject(XmlReader reader)
    {
        CheckNull(reader, 
"reader");
        
return this.ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader));
    }
    
public abstract object ReadObject(XmlDictionaryReader reader, bool
verifyObjectName);
    
public virtual object ReadObject(XmlReader reader, bool verifyObjectName)
    {
        CheckNull(reader, 
"reader");
        
return this.ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader),
verifyObjectName);
    }

    
public abstract void WriteEndObject(XmlDictionaryWriter writer);
    
public virtual void WriteEndObject(XmlWriter writer)
    {
        CheckNull(writer, 
"writer");
        
this.WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer));
    }
    
public virtual void WriteObject(XmlDictionaryWriter writer, object graph)
    {
        CheckNull(writer, 
"writer");
        
try
        {
            
this.WriteStartObject(writer, graph);
            
this.WriteObjectContent(writer, graph);
            
this.WriteEndObject(writer);
        }
        
catch (XmlException exception)
        {
            
throw new SerializationException(GetTypeInfoError(0this.GetSerializeTy
pe(graph), exception), exception);
        }
        
catch (FormatException exception2)
        {
            
throw new SerializationException(GetTypeInfoError(0this.GetSerializeTy
pe(graph), exception2), exception2);
        }
    }
    
public virtual void WriteObject(XmlWriter writer, object graph)
    {
        CheckNull(writer, 
"writer");
        
this.WriteObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
    }
    
public abstract void WriteObjectContent(XmlDictionaryWriter writer, object
graph);
    
public virtual void WriteObjectContent(XmlWriter writer, object graph)
    {
        CheckNull(writer, 
"writer");
        
this.WriteObjectContent(XmlDictionaryWriter.CreateDictionaryWriter(writer),
graph);
    }
    
public abstract void WriteStartObject(XmlDictionaryWriter writer, object graph);
    
public virtual void WriteStartObject(XmlWriter writer, object graph)
    {
        CheckNull(writer, 
"writer");
        
this.WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer),
 graph);
    }
}

  我们可以再服务操作里使用数据契约类型参数或者返回此类型的结果,WCF框架会自动使用DataContractSerializer对参数或者结果进行序列化合反序列化。.NET 的内建基本类型如String、int等默认具有数据契约的特性,支持公开的标准,因此都是可以序列化的。

0
0
标签:WCF

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻