解析.Net 框架下的序列化机制

合集下载

.NET对象的XML序列化和反序列化

.NET对象的XML序列化和反序列化

.NET对象的XML序列化和反序列化序列化是指⼀个对象的实例可以被保存,保存成⼀个⼆进制串,当然,⼀旦被保存成⼆进制串,那么也可以保存成⽂本串了。

⽐如,⼀个计数器,数值为2,我们可以⽤字符串“2”表⽰。

如果有个对象,叫做connter,当前值为2,那么可以序列化成“2”,反向的,也可以从“2”得到值为2的计数器实例。

这样,关机时序列化它,开机时反序列化它,每次开机都是延续的。

不会都是从头开始。

序列化概念的提出和实现,可以使我们的应⽤程序的设置信息保存和读取更加⽅便。

序列化有很多好处,⽐如,在⼀台机器上产⽣⼀个实例,初始化完毕,然后可以序列化,通过⽹络传送到另⼀台机器,然后反序列化,得到对象实例,之后再执⾏某些业务逻辑,得到结果,再序列化,返回第⼀台机器,第⼀台机器得到对象实例,得到结果。

这个例⼦是⽬前⽐较先进的“智能代理”的原理。

当前⽐较热⽕的web services使⽤soap协议,soap协议也是以对象的可序列化为基础的。

⼀概述.NET Framework为处理XML数据提供了许多不同的类库。

XmlDocument类能让你像处理⽂件⼀样处理xml数据,⽽XmlReader、XmlWriter和它们的派⽣类使你能够将xml数据作为数据流处理。

XmlSerializer则提供了另外的⽅法,它使你能够将⾃⼰的对象串⾏化和反串⾏化为xml。

串⾏化数据既能够让你像处理⽂件⼀样对数据进⾏随机处理,同时⼜能跳过你不感兴趣的数据。

⼆主要类库介绍.NET ⽀持对象xml序列化和反序列化的类库主要位于命名空间System.Xml.Serialization中。

1. XmlSerializer 类该类⽤⼀种⾼度松散耦合的⽅式提供串⾏化服务。

你的类不需要继承特别的基类,⽽且它们也不需要实现特别的接⼝。

相反,你只需在你的类或者这些类的公共域以及读/写属性⾥加上⾃定义的特性。

XmlSerializer通过反射机制读取这些特性并⽤它们将你的类和类成员映射到xml元素和属性。

.net反序列化漏洞原理

.net反序列化漏洞原理

.net反序列化漏洞原理
.NET反序列化漏洞是一种安全漏洞,它涉及到.NET应用程序中
的反序列化过程。

在.NET中,反序列化是将序列化的数据转换为对
象的过程。

当应用程序从外部源(如网络、文件等)接收序列化数
据并对其进行反序列化时,如果未对输入进行充分验证和过滤,就
可能导致反序列化漏洞。

攻击者可以利用这种漏洞来执行恶意代码,进行远程代码执行等攻击。

具体原理是,攻击者通过构造恶意的序列化数据,利用.NET反
序列化过程中的漏洞触发恶意代码执行。

这可能涉及到利用.NET框
架中的一些反序列化函数或特性,如BinaryFormatter、DataContractSerializer等。

攻击者可以通过修改序列化数据中的
类型信息、构造恶意对象图等方式来欺骗应用程序,使其在反序列
化过程中执行恶意代码。

为防范.NET反序列化漏洞,开发人员应该对反序列化输入进行
严格的验证和过滤,避免直接反序列化不受信任的数据。

同时,可
以考虑使用安全的序列化库、限制反序列化的类型等措施来降低漏
洞风险。

另外,及时更新.NET框架和相关组件也是防范漏洞的重要
措施。

综上所述,了解.NET反序列化漏洞的原理并采取相应的安全措施对于保护.NET应用程序的安全至关重要。

序列化与反序列化,及Json序列化反序列化

序列化与反序列化,及Json序列化反序列化

序列化是将对象状态转换为可保持或可传输的格式的过程,反序列化则过程相反。

用于存储和传输数据。

(一)序列化与反序列化.net提供多种序列化类(1)BinaryFormatter 类名字空间:System.Runtime.Serialization.Formatters.Binary这个类用于以二进制格式将对象或整个连接对象图形序列化和反序列化构造器两个:BinaryFormatter()BinaryFormatter(ISurrogateSelector, StreamingContext)介绍它的两个主要方法:1 Serialize方法将对象或连接对象图形序列化为给定流它有两个重载:Serialize(Stream, Object)Serialize(Stream, Object,Header[])类Customerpublic class Customer{public int Unid { get; set; }public string Name { get; set; }public string Call { get; set; }}下边通过示例来测试序列化方法Serializepublic void TestSerialize(){Customer customer = new Customer {Unid=1,Name="宋江",Call="89589689"};FileStream fs = new FileStream("test.dat",FileMode.Create);BinaryFormatter formatter = new BinaryFormatter();try{formatter.Serialize(fs, customer);}catch{}finally{fs.Close();}}测试时,这个会抛出异常:类型“SerializeTest.Customer”未标记为可序列化。

net下二进制序列化的格式分析

net下二进制序列化的格式分析

.net下二进制序列化的格式分析相应c#下的序列化代码如下所示,程序把序列化后的数据存入了一个指定的文件file.bin里,分析这个文件数据主要为了能让非.Net下的应用程序读取序列化后数据,这有助于.net与其他语言平台的交互.using System;using System.Drawing;using System.Collections;using ponentModel;using System.Windows.Forms;using System.Data;namespace WindowsApplication2{[Serializable]public class Object5{public int i1 = 0;public int i2 = 0;public float f3=0;public string str;}public class Form1 : System.Windows.Forms.Form{private System.Windows.Forms.Button button1;private ponentModel.Container components = null;public Form1(){InitializeComponent();}protected override void Dispose( bool disposing ){if( disposing ){if (components != null){components.Dispose();}}base.Dispose( disposing );}#region Windows 窗体设计器生成的代码private void InitializeComponent(){this.button1 = new System.Windows.Forms.Button();this.SuspendLayout();this.button1.Location = new System.Drawing.Point(72, 72); = "button1";this.button1.Size = new System.Drawing.Size(128, 32);this.button1.TabIndex = 0;this.button1.Text = "button1";this.button1.Click += new System.EventHandler(this.button1_Click);this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);this.ClientSize = new System.Drawing.Size(292, 273);this.Controls.Add(this.button1); = "Form1";this.Text = "Form1";this.ResumeLayout(false);}#endregion[STAThread]static void Main(){Application.Run(new Form1());}private void button1_Click(object sender, System.EventArgs e){Object5 obj = new Object5();obj.i1 = 128;obj.i2 = 24;obj.f3=1.3f;obj.str = "Some String";double d1=1.3d;float f1=1.3f;int i1=1;string s1="HelloWorld";System.Runtime.Serialization.IFormatter formatter = newSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter();System.IO.Stream stream = new System.IO.FileStream("File.bin", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None);formatter.Serialize(stream, obj);formatter.Serialize(stream,d1);formatter.Serialize(stream,f1);formatter.Serialize(stream,i1);formatter.Serialize(stream,s1);stream.Close();formatter=null;}}}文件内容如下图所示:注解:1 )00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 序列化头,经过实践分析,这部分基本在每个序列化后的数据都一样,下面也可以看到与其他的一样2 )0C 02 被序列化后对象描述信息的表示符3 )00 00 00 51(81)长度,(注意是大端的4位整型),说明后面对象描述信息的长度4 )自定义对象的描述信息,分析时可以忽略,长度为81个字符(前一项以说明)5 )05 01自定义对象的表示符 .6 )00 00 00 1b (27)自定义对象类描述信息的长度7 )自定义对象的描述信息,主要类的符号表示(“WindowsApplication2.Object5”)8 )自定义对象中的成员条目,例如在上面定义的对象中有四项,分别为int、int、flaot 和string9 )02 长度为2的int i1成员10 )对应成员名称的定义标示“i1”11 )同9项12 )同10项13 )同9项14 )同10项15 )同9项16 )同10项17 )说明自定义对象的各个定义项目是值对象还是其他类型,一共4个字节,00为值对象01为字符对象在上面定义的对象为int i1 int i2 float f1 string str 对应为00 00 00 01 。

C#:.net序列化及反序列化[XmlElement(“节点名称”)][XmlAttrib。。。

C#:.net序列化及反序列化[XmlElement(“节点名称”)][XmlAttrib。。。

C#:.net序列化及反序列化[XmlElement(“节点名称”)][XmlAttrib。

.NET Framework 开发员指南序列化是将对象转换为容易传输的格式的过程。

例如,可以序列化⼀个对象,然后使⽤ HTTP 通过 Internet 在客户端和服务器之间传输该对象。

在另⼀端,反序列化将从该流重新构造对象。

XML 序列化仅将对象的公共字段和属性值序列化为 XML 流。

XML 序列化不包括类型信息。

例如,如果您有⼀个存在于 Library 命名空间中的 Book 对象,将不能保证它将会被反序列化为同⼀类型的对象。

注意 XML 序列化不转换⽅法、索引器、私有字段或只读属性(只读集合除外)。

若要序列化对象的所有字段和属性(公共的和私有的),请使⽤,⽽不要使⽤ XML序列化。

XML 序列化中最主要的类是类,它的最重要的⽅法是 Serialize 和 Deserialize ⽅法。

XmlSerializer ⽣成的 XML 流符合万维⽹联合会 () XML 架构定义语⾔ (XSD)1.0 的建议。

另外,⽣成的数据类型符合标题为“XML Schema Part 2: Datatypes”(XML 架构第⼆部分:数据类型)的⽂档。

对象中的数据是⽤编程语⾔构造(如类、字段、属性、基元类型、数组,甚⾄ XmlElement 或 XmlAttribute 对象形式的嵌⼊ XML)来描述的。

您可以创建⾃⼰的⽤属性批注的类,或者使⽤ XML 架构定义⼯具⽣成基于现有 XML 架构的类。

如果您有 XML 架构,就可运⾏ XML 架构定义⼯具⽣成⼀组强类型化为架构并⽤属性批注的类。

当序列化这样的类的实例时,⽣成的 XML 符合 XML 架构。

使⽤这样的类,就可针对容易操作的对象模型进⾏编程,同时确保⽣成的 XML 符合 XML 架构。

这是使⽤ .NET Framework 中的其他类(如 XmlReader 和 XmlWriter 类)分析和写 XML 流的⼀种替换⽅法。

XML序列化

XML序列化

XML序列化.NET框架提供的一种形式的序列化是XML序列化。

在这种类型的序列化里,对象状态被以XML格式保存。

这使得被序列化的对象能够被不同的系统取得并修改,甚至是那些不是用.NET编写的系统。

另外一个优势是被序列化的对象对于人来说是可读和可写的——因此更新对象的方式莫过于打开写字板更改其值。

XML序列化常常被来远程控制项目和Web服务项目里,虽然你可能会在别的地方发现它,比如DataSet封送。

在与Xpath查询和Predicate方法一起使用的时候,XML序列化能够被用来实现面向对象的数据库。

使用XML序列化在.NET框架里利用内置的XML序列化方法相对较为容易。

你只需要熟悉一些类和属性就可以开始使用简单的XML序列化了:System.Xml.Serialization命名空间:含有使用XML序列化所需要的类和功能。

这个命名空间应该被放在使用XML序列化的类的顶部的一个“using”命令里。

XmlSerializer类:提供将对象序列化和反序列化的功能。

XmlIgnore属性:告诉XmlSerializer类跳过你不希望序列化的成员。

这个列表只不过让你对序列化有一个初步的了解。

还有更多的对象可以供你在使用XML序列化的时候使用。

列表A是将Customer对象序列化的一个简单例子。

这个Customer对象在下载文件的示例应用程序里被定义。

列表A1.Customer customer = newCustomer();2.customer.FirstName = "Zach";stName = "Smith";4.XmlSerializer serializer = newXmlSerializer(typeof(Customer));5.StringWriter writer = newStringWriter();6.serializer.Serialize(writer, customer);7.Console.WriteLine(writer.ToString());复制代码正如你看到的,XML序列化是一个很简单的过程。

.net中的序列化

.net中的序列化

.net中的序列化
在.net中,常见的序列化格式主要有json,⼆进制和xml,总结如下表格。

关于实体特性标注规则:
1,.net中所有⽤于序列化的实体的class上应该加上[Serializable]标记,如果不加的话,json序列化的时候没有问题,但是使⽤BinaryFormatter进⾏⼆进制序列化的时候就会报错。

2,如果应⽤在wcf中,所有实体的class上还应该加上[DataContract]标记,字段上要加[DataMember]。

3,在使⽤newtonsoft.json的时候,如果实体类加了[DataContract],有些字段加了[DataMember],⽽有些字段没有加,但是序列化的时候也要包含那些没有加[DataMember]的字段,可以在实体类上加[JsonObject(MemberSerialization.OptOut)]来解决,表⽰输出全部的公共字段。

4,使⽤newtonsoft.json时,System.Web.UI.WebControls.ListItem不能序列化,解决⽅法是,⾃定义⼀个类并标记[Serializable]。

1,如果是json格式,NewtonSoft.Json最通⽤(可以处理循环引⽤),虽然它不是速度最快的。

2,如果是xml格式,就使⽤.net⾃带的XmlSerializer。

3,如果是⼆进制格式,就使⽤.net⾃带的BinaryFormatter,虽然Protobuf速度很快,但是要加序号很⿇烦。

.NET中XML序列化和反序列化常用类和属性小结

.NET中XML序列化和反序列化常用类和属性小结

.NET中XML序列化和反序列化常⽤类和属性⼩结⽬录序列化和反序列化是指什么?XmlSerializer类.NET-XML序列化和反序列化简单⽰例代码XmlTypeAttribute类应⽤⽰例XmlElementAttribute类应⽤⽰例XmlAttributeAttribute类应⽤⽰例XmlArrayAttribute类应⽤⽰例XmlTextAttribute类应⽤⽰例XmlIgnoreAttribute类应⽤⽰例⽤来控制XML序列化的属性汇总参考⽂章序列化和反序列化是指什么?序列化(seriallization):将对象转化为便于传输的数据格式,常见的序列化格式:⼆进制格式,字节数组,json字符串,xml 字符串。

反序列化(deseriallization):将序列化的数据恢复为对象的过程。

XmlSerializer类 该类⽤⼀种⾼度松散耦合的⽅式提供串⾏化服务。

你的类不需要继承特别的基类,⽽且它们也不需要实现特别的接⼝。

相反,你只需在你的类或者这些类的公共域以及读/写属性⾥加上⾃定义的特性。

XmlSerializer通过反射机制读取这些特性并⽤它们将你的类和类成员映射到xml元素和属性(在对象和 XML ⽂档之间进⾏序列化和反序列化操作)。

.NET-XML序列化和反序列化简单⽰例代码using System.IO;using System.Xml.Serialization;namespace mon{public class SimpleSerializer{/// <summary>/// Model实体对象序列化为XML字符串/// </summary>/// <typeparam name="T">对象类型</typeparam>/// <param name="t">Model实体对象</param>/// <returns></returns>public static string SerializeXMLL<T>(T t){using (StringWriter sw = new StringWriter()){XmlSerializer xmlSerializer = new XmlSerializer(t.GetType());xmlSerializer.Serialize(sw, t);return sw.ToString();}}/// <summary>/// XML反序列化为对象/// </summary>/// <typeparam name="T">对象类型</typeparam>/// <param name="xml">xml字符串</param>/// <returns></returns>public static T Deserialize<T>(string xml){XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));StringReader stringReader = new StringReader(xml);return (T)xmlSerializer.Deserialize(stringReader);}}}XmlTypeAttribute类 该类主要控制当属性⽬标由XML序列化时⽣成的XML节点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

解析.Net框架下的序列化机制程序员在编写应用程序的时候往往要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯。

这个将程序数据转化成能被存储并传输的格式的过程被称为"序列化"(Serialization),而它的逆过程则可被称为"反序列化"(Deserialization)。

.Net框架对序列化机制具有非常好的支持,它提供了两个名字空间(namespace):System.Runtime.Serialization和System.Runtime.Serialization.Formatters以完成序列化机制的大部分功能。

系列化这项技术可以应用在将程序产生的结果数据存储到文件系统中,但是它更主要的应用是在于.Net Remoting和Web服务的实现上。

序列化机制的实现是依靠格式器(Formatter)而完成的,它是一个从System.Runtime.Serialization.IFormatter继承下来的类的对象。

格式器完成了将程序数据转化到能被存储并传输的格式的工作,同时也完成了将数据转化回来的工作。

.Net框架为程序员提供了两种类型的格式器,一种通常是应用于桌面类型的应用程序的,它一个是System.Runtime.Serialization.Formatters.Binary.BinaryFormatter类的对象,而另一种则更主要的应用于.Net Remoting和XML Web服务等领域的,它一个是System.Runtime.Serialization.Formatters.Soap.SoapFormatter类的对象。

从它们的名称来看,我们不妨将它们分别称为二进制格式器和XML格式器。

本文将从这两个格式器入手,先向大家介绍分别用它们如何实现序列化和反序列化,然后比较两种格式器的不同点。

接着我会向大家介绍实现序列化对对象类型的一些要求,同时还要向大家介绍两种不同的序列化方式:基本序列化(Basic Serialization)和自定义序列化(Custom Serialization)。

最后,我还会给大家介绍一个实例程序以加深大家对序列化机制的理解程度。

一.二进制格式器(Binary Formatter)vs XML格式器(XML Formatter):下面我先向大家介绍两种不同的格式器,分别用它们如何实现序列化机制和反序列化机制,请看下面的代码:#region Binary Serializerspublic static System.IO.MemoryStream SerializeBinary(object request) {System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer =new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();System.IO.MemoryStream memStream = new System.IO.MemoryStream();serializer.Serialize(memStream, request);return memStream;}public static object DeSerializeBinary(System.IO.MemoryStream memStream) {memStream.Position=0;System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();object newobj = deserializer.Deserialize(memStream);memStream.Close();return newobj;}#endregion#region XML Serializerspublic static System.IO.MemoryStream SerializeSOAP(object request) {System.Runtime.Serialization.Formatters.Soap.SoapFormatter serializer =new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();System.IO.MemoryStream memStream = new System.IO.MemoryStream();serializer.Serialize(memStream, request);return memStream;}public static object DeSerializeSOAP(System.IO.MemoryStream memStream) {object sr;System.Runtime.Serialization.Formatters.Soap.SoapFormatter deserializer =new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();memStream.Position=0;sr = deserializer.Deserialize(memStream);memStream.Close();return sr;}#endregion从上面的代码我们可以发现无论运用哪种格式器,其基本的过程都是一样的,而且都是非常容易实现的,唯一的不同就是定义格式器的类型不同。

不过在实际的应用中,二进制格式器往往应用于一般的桌面程序和网络通讯程序中,而XML格式器禀承了XML技术的优点,大多数被应用于.Net Remoting和XML Web服务等领域。

下面我们来分析一下两种格式器各自的优点。

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

XML序列化的优点:1.互操作性好;2.不需要严格的二进制依赖;3.可读性强。

通过分析上面的代码,我们知道了选择二进制序列化的方式还是选择XML序列化的方式仅仅是对不同的格式器进行选择而已。

你可以根据实际的需要选择相应的格式器完成序列化和反序列化工作。

同时请注意,代码中的序列化函数和反序列化函数仅仅是在调用Serialize()和Deserialize()这两个核心函数上产生了差别,即它们的参数不同。

因此以上的代码完成了一些最最基本但是很重要的功能,你可以将它们运用在你的程序中,或是将其进行适当扩充以满足程序的特定需要。

二.序列化机制对类的要求:如果你要对一个对象进行序列化,那么你必须将它的类型标记为[Serializable()],该操作是通过SerializableAttribute属性来实现的。

将SerializableAttribute属性应用于一种数据类型可表明该数据类型的实例可以被序列化。

如果正在序列化的对象图中的任何类型未应用SerializableAttribute属性,公共语言运行库则会引发SerializationException。

默认情况下,类型中由SerializableAttribute标记的所有公共和私有字段都会进行序列化,除非该类型实现ISerializable接口来重写序列化进程(通过实现该接口我们便可以实现将在后面介绍的"自定义序列化")。

默认的序列化进程会排除用NonSerializedAttribute属性标记的字段,即你可以将该类型标记为[NonSerialized()]以表明它是不可以被序列化的。

如果可序列化类型的字段包含指针、句柄或其他某些针对于特定环境的数据结构,并且不能在不同的环境中以有意义的方式重建,则最好将NonSerializedAttribute属性应用于该字段。

有关序列化的更多信息,请参阅System.Runtime.Serialization名字空间中的相关内容。

下面我给大家介绍一个例子,以显示如何正确的运用SerializableAttribute属性和NonSerializedAttribute属性。

该程序中运用到了XML格式器,不过同时给出了二进制格式器为参考(程序中将其用"//"标注),其实现的结果是一样的。

该程序实现的功能是在序列化和反序列化操作前后测试对象因包含了[NonSerialized()]的字段而显示不同的屏幕打印结果。

其代码如下:using System;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Soap;//using System.Runtime.Serialization.Formatters.Binary;public class Test {public static void Main() {// 创建一个新的测试对象TestSimpleObject obj = new TestSimpleObject();Console.WriteLine("Before serialization the object contains: ");obj.Print();// 创建一个文件"data.xml"并将对象序列化后存储在其中Stream stream = File.Open("data.xml", FileMode.Create);SoapFormatter formatter = new SoapFormatter();//BinaryFormatter formatter = new BinaryFormatter();formatter.Serialize(stream, obj);stream.Close();// 将对象置空obj = null;// 打开文件"data.xml"并进行反序列化得到对象stream = File.Open("data.xml", FileMode.Open);formatter = new SoapFormatter();//formatter = new BinaryFormatter();obj = (TestSimpleObject)formatter.Deserialize(stream);stream.Close();Console.WriteLine("");Console.WriteLine("After deserialization the object contains: ");obj.Print();}}// 一个要被序列化的测试对象的类[Serializable()]public class TestSimpleObject {public int member1;public string member2;public string member3;public double member4;// 标记该字段为不可被序列化的[NonSerialized()] public string member5;public TestSimpleObject() {member1 = 11;member2 = "hello";member3 = "hello";member4 = 3.14159265;member5 = "hello world!";}public void Print() {Console.WriteLine("member1 = '{0}'", member1);Console.WriteLine("member2 = '{0}'", member2);Console.WriteLine("member3 = '{0}'", member3);Console.WriteLine("member4 = '{0}'", member4);Console.WriteLine("member5 = '{0}'", member5);}}三.基本序列化(Basic Serialization)vs 自定义序列化(Custom Serialization):.Net框架为我们提供了两种方式的序列化:一种为基本序列化、另一种为自定义序列化。

相关文档
最新文档