深入理解:XML与对象的序列化与反序列化

这篇文章主要讲述XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。
假设我们在一个Web项目中有这样两个类


代码如下:

public class Member
    {
      public string Num { get; set; }
      public string Name { get; set; }
    }
    public class Team
    {
       public  string Name;
       public  List<Member> Members { get; set; }
    }

假设我们需要把Team类的一个实例POST到一个URL,
当然,使用Form隐藏域提交就可以完成该功能。
如果该Team包括30条数据呢?
为了区分每个Member,我们得给参数的名字加上后缀。这就要一大串的隐藏域来完成:


代码如下:

<!--使用Razor来演示-->
@model Team
<form id="submitForm" action="http://www.johnconnor.com/team" method="post">
<input type="hidden" name="TeamName" value="@Model.Name" />
<input type="hidden" name="MemberNum1" value="@Model.Members[0].Num" />
<input type="hidden" name="MemberName1" value="@Model.Members[0].Name" />
...
<!--省略28X2个input标签-->
<input type="hidden" name="MemberNum30" value="@Model.Members[29].Num" />
<input type="hidden" name="MemberName30" value="@Model.Members[29].Name" />
</form>
<script type="text/javascript">
    document.getElementById("submitForm").submit();
</script>

还敢想象一下如果Team再复杂一些,嵌套再多一些的情况么?
呃,即使你愿意这么传数据,对方看到一坨参数名就够头疼了。
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。
XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。以Team类为例:


代码如下:

<?xml version="1.0" encoding="utf-8"?>
<Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Development</Name>
  <Members>
    <Member>
      <Num>001</Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Num>002</Num>
      <Name>John</Name>
    </Member>
  </Members>
</Team>

这样一个XML文档就表示了Team一个实例。
聪明的看官应该已经想到,XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?

XmlSerializer类就是干这个活的。
      命名空间:System.Xml.Serialization
     程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类。
Deserialize方法将XML字符串转换为指定类型的对象;
Serialize方法则将对象转换为XML字符串。


代码如下:

/// <summary>
    /// 提供xml文档序列化 反序列化
    /// </summary>
    public sealed class EncodeHelper
    {
        /// <summary>
        /// 反序列化XML字符串为指定类型
        /// </summary>
        public static object Deserialize(string Xml, Type ThisType)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(ThisType);
            object result;
            try
            {
                using (StringReader stringReader = new StringReader(Xml))
                {
                    result = xmlSerializer.Deserialize(stringReader);
                }
            }
            catch (Exception innerException)
            {
                bool flag = false;
                if (Xml != null)
                {
                    if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
                    {
                        flag = true;
                    }
                }
                throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.",
                Xml, flag, ThisType.FullName), innerException);
            }
            return result;
        }
        /// <summary>
        /// 序列化object对象为XML字符串
        /// </summary>
        public static string Serialize(object ObjectToSerialize)
        {
            string result = null ;
            try
            {
            XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());

using (MemoryStream memoryStream = new MemoryStream())
            {
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);
                xmlTextWriter.Flush();
                xmlTextWriter.Close();
                UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
                result= uTF8Encoding.GetString(memoryStream.ToArray());
            }
            }
            catch (Exception innerException)
            {
                throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);
            }
            return result;
        }
    }

要使用这个类需要添加以下引用
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
下面我们用一个控制台程序来演示一下这个类是如何工作的。这里是程序的Main函数。


代码如下:

static void Main(string[] args)
        {
            List<Member> Members = new List<Member>();
            Member member1 = new Member { Name = "Marry", Num = "001" };
            Member member2 = new Member { Name = "John", Num = "002" };
            Members.Add(member1);
            Members.Add(member2);
            Team team = new Team { Name = "Development", Members = Members };
            var xml =EncodeHelper.Serialize(team);//序列化
            Console.Write(xml);//打印序列化后的XML字符串
            Console.ReadLine();
            Team newTeam = EncodeHelper.Deserialize(xml, typeof(Team)) as Team;//反序列化时需要显式的进行类型转换
            Console.WriteLine("Team Name:"+newTeam.Name);//显示反序列化后的newTeam对象
            foreach (var member in newTeam.Members)
            {
                Console.WriteLine("Member Num:" + member.Num);
                Console.WriteLine("Member Name:" + member.Name);
            }
            Console.ReadLine();
        }

在执行完Console.Write(xml)这行代码后,就可以看到打印出来的XML文档了。


代码如下:

<?xml version="1.0" encoding="utf-8"?>
<Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Development</Name>
  <Members>
    <Member>
      <Num>001</Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Num>002</Num>
      <Name>John</Name>
    </Member>
  </Members>
</Team>

与我在文章开头给出的例子是一模一样的。
最终反序列化出来的newTeam对象打印出来是这样的结果。
Team Name:Development
Member Num:001
Member Name:Marry
Member Num:002
Member Name:John
回到我们开头的Web通信的例子,
利用XML序列化与反序列化来进行对象传递,我们只需要把需要传递的对象序列化为XML字符串,使用一个隐藏域进行form提交就可以搞定咯!
接收方再将接收到的XML字符串反序列化成预设的对象即可。前提是双方必须约定序列化与反序列化的过程一致,且对象相同。

最后我们来看一下怎么利用一些特性来控制序列化与反序列化操作的过程。我们把开始的类改一下:


代码如下:

public class Member
    {
        [XmlElement("Member_Num")]
        public string Num { get; set; }
        public string Name { get; set; }
    }
    [XmlRoot("Our_Team")]
    public class Team
    {
        [XmlIgnore]public string Name;
        public List<Member> Members { get; set; }
    }

然后我们再次执行刚才的控制台程序,序列化结果变成了这样:


代码如下:

<?xml version="1.0" encoding="utf-8"?>
<Our_Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Members>
    <Member>
      <Member_Num>001</Member_Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Member_Num>002</Member_Num>
      <Name>John</Name>
    </Member>
  </Members>
</Our_Team>

本来的根节点Team变成了Our_Team,Member的子节点Num变成了Member_Num,并且Team的Name子节点被忽略了。
可见特性XmlRoot可以控制根节点的显示和操作过程,XmlElement则针对子节点。如果某些成员被标记XmlIgnore,则在序列化与反序列化过程中会被忽略。
这些特性的具体内容可以在MSDN查看,就不多讲了。
有了这些知识,在网络中传递对象数据应该已经难不倒各位看官了把。^_^

(0)

相关推荐

  • Jquery 组合form元素为json格式,asp.net反序列化

    作者:敖士伟 Email:ikmb@163.com 转载注明作者 说明: 1.js根据表单元素class属性,把表单元素的name和value组合为json格式;用表单元素class属性可以针对性地组合JSON数据. 2.后端ASP.NET用JavaScriptSerializer反序列化为对象实列. 3.好处:简化了前端数据读取与后端数据赋值. 复制代码 代码如下: function GetJSONStr(class_name) { var a = []; //文本框 $("." +

  • asp.net xml序列化与反序列化第1/2页

    在网上找了一些关于xml序列化与反序列化的资料,摘录下:        在.NET下有一种技术叫做对象序列化,它可以将对象序列化为二进制文件.XML文件.SOAP文件,这样, 使用经过序列化的流进行传输效率就得到了大大的提升. 在.NET中提供了两种序列化:二进制序列化.XML和SOAP序列化.对于WEB应用来说,用得最多的是第二种---XML和SOAP序列化. XML 序列化将对象的公共字段和属性或者方法的参数和返回值转换(序列化)为符合特定 XML 架构定义 语言 (XSD) 文档的 XML

  • c#数据的序列化和反序列化(推荐版)

    开始用的.net 自带的DataContractJsonSerializer进行序列化和反序列化,当代码写完以后,调试,我X(原谅我的脏话,因为确实让我生气),实体因为有[DataContractAttribute(IsReference=true )] 这样一个属性,提示不能序列化,当然手改一下啦,改完以后,提示基类EntityObject 的这个属性不可以 MY God!! 后来也是因为DataContractJsonSerializer 反序列化成集合的时候不好使,所以才下定决心废弃.采用

  • C#实现json的序列化和反序列化实例代码

    在做asp.net和unity进行http通信的时候,当unity客户端发出表单请求的时候,我要将他要请求的数据以json的格式返回给客户端,让客户端来解析.服务器端这一块就涉及到json的序列化和反序列化的问题. 两种方法都有例子,第一种是用泛型集合来存储的对象,然后将集合序列化一下:第二种是直接序列化的一个对象 复制代码 代码如下: using System;using System.Collections.Generic;using System.Web.Script.Serializat

  • c#对象反序列化与对象序列化示例详解

    1.对象序列化的介绍 (1).NET支持对象序列化的几种方式二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下.SOAP序列化:对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP 协议传输,通过System.Runtime.Serialization.Formatters.Soap命名空间下的SoapFormatter类来实现的.XML

  • ASP.NET中JSON的序列化和反序列化使用说明

    在网站应用中使用JSON的场景越来越多,本文介绍 ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍,ASP.NET如何序列化和反序列化的处理,在序列化和反序列化对日期时间.集合.字典的处理. 一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大括号'{}',中括号'[]',逗号',',冒号':',双引号'""'组成,包含

  • c#正反序列化XML文件示例(xml序列化)

    复制代码 代码如下: using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Text;using System.Text.RegularExpressions;using System.Xml.Serialization;using System.IO;using System; namespace GlobalTimes.Framework{    /// <summar

  • .net实现序列化与反序列化实例解析

    序列化与反序列化是.net程序设计中常见的应用,本文即以实例展示了.net实现序列化与反序列化的方法.具体如下: 一般来说,.net中的序列化其实就是将一个对象的所有相关的数据保存为一个二进制文件(注意:是一个对象) 而且与这个对象相关的所有类型都必须是可序列化的所以要在相关类中加上 [Serializable]特性 对象类型包括:对象本身包含的类型,父类 拥有需要的对象之后: 1.将对象转换为二进制数据 使用专门的对像进行转换 BinaryFormatter 2.将二进制数据写入到文件 Fil

  • asp.net 序列化and反序列化演示

    什么是序列化? ---.net的运行时环境用来支持用户定义类型的流化的机制.它是将对象实例的状态存储到存储媒体的过程.在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流.在随后对对象进行反序列化时,将创建出与原对象完全相同的副本. 序列化的目的: 1.以某种存储形式使自定义对象持久化: 2.将对象从一个地方传递到另一个地方. 实质上序列化机制是将类的值转化为一个一般的(即连续的)字节流,然后就可以将该流写到磁盘文件或任何其他流化目标上

  • 深入理解:XML与对象的序列化与反序列化

    这篇文章主要讲述XML与对象的序列化与反序列化.并且会附上一些简单的序列化与反序列化方法,供大家使用.假设我们在一个Web项目中有这样两个类 复制代码 代码如下: public class Member     {      public string Num { get; set; }      public string Name { get; set; }    }    public class Team    {       public  string Name;       pub

  • 详解 C# 中XML对象的序列化和反序列化

    这一篇主要是用来介绍关于C#中的XML序列化的问题,这个相信大家一定会经常使用它,特别是在WPF中,有时候我们需要将我们后台的数据保存在数据库中,从而在软件下一次启动的时候能够自动去加载这些数据,由于我们的这些Model中字段众多,如果单独进行保存那是不太现实的,这个时候将这些字段序列化成xml字符串并保存在数据库中就是一个不错的选择,当我们需要这些数据的时候我们也可以反过来将其序列化为一些字段,最终达到我们的效果,首先我们来看看是如何实现的? public class XMLUtil {   

  • Java IO流对象的序列化和反序列化实例详解

    Java-IO流 对象的序列化和反序列化 序列化的基本操作 1.对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化. 2.序列化流(ObjectOutputStream),writeObject 方法用于将对象写入输出流中: 反序列化流(ObjectInputStream),readObject 方法用于从输入流中读取对象. 3.序列化接口(Serializeable) 对象必须实现序列化接口,才能进行序列化,否则会出现异常.这个接口没有任何方法,只是一个标准. packag

  • java对象的序列化和反序列化

    本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化        将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化.(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化        需要实现Serializable接口,java对象实现了这个接口就表明这个这个类的对象是可序列化的. 3. 序列化的注意事项 (1) 当一个对象序列化时,只能保存对象的非静态成员变量,不能保存方法和静态成员变

  • 深入理解Java对象的序列化与反序列化的应用

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为Java对象. 把Java对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为Java对象的过程称为对象的反序列化.对象的序列化主要有两种用途:1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中:2) 在网络上传送对象的字节序列.一. JDK类库中的序列化APIjava.io

  • C#实现对象的序列化和反序列化

    什么是序列化和反序列化: 将对象及其状态保存起来,通常是保存到文件中,叫序列化.将文件还原为对象,叫反序列化. 序列化和反序列化的接口和帮助类: 接口IFormatter object Deserialize(Stream serializactionStream) void Serialize(Stream serializationStream, object graph) System.Runtime.Serialization.Formatters.Binary下的BinaryForma

  • Java对象的序列化与反序列化详解

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种途径: Ⅰ . 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 Ⅱ.  在网络上传送对象的字节序列. 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为Java对象. 二.序列化API 1.

  • java 对象的序列化和反序列化详细介绍

    最近周末,对java 的基础知识做了一个整理,其中java 序列化和反序列化的资料进行了详细整理,这里做个笔记,希望也能帮助到读到此文的朋友. 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是

  • java中对象的序列化与反序列化深入讲解

    引言: 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是为了解决在对对象流进行读写操作时所引发的问题. 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对 象,当有 10万用户并发访问,就有可能出现10万个Session对

  • 实例分析java对象的序列化和反序列化

    引言: 序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创建对象的过程,此对象来自于临时或持久储存区. 序列化的作用: 就好比如存储数据到数据库,将一些数据持久化到数据库中,而有时候需要将对象持久化,虽然说将对象状态持久化的方式有很多,但是java给我们提供了一种很便捷的方式,那就是序列化,序列化可以实现对象到文件之间的直接转换,实现细节对我们隐藏. 具体的三种用途: •将对象的状态信息持久化保存到硬盘上 •将对

随机推荐