浅谈.Net中的序列化和反序列化_实用技巧

来源:脚本之家  责任编辑:小易  

通常用在需要利用ajax进行页面无刷新交互的情况下。比如将服务器端的datatable中数据序列化为json对象,然后在前台用js脚本进行解析显示。json对象用起来很方便,不像xml解析那样繁琐,而且占用的资源要小www.zgxue.com防采集请勿采集本网。

序列化和反序列化相信大家都经常听到,也都会用, 然而有些人可能不知道:.net为什么要有这个东西以及.net Frameword如何为我们实现这样的机制, 在这里我也是简单谈谈我对序列化和反序列化的一些理解。

这个跟反序列化毫无关系。 分隔字符串就用 Split(),没什么难度。

一、什么序列化和反序列化

序列化和反序列化并不是C#独有的,包括java、php、js等都可以做到。 序列化是将对象 与序列化相对的是反序列化,它将流转换为对象,也就是将在序列化过程中所生成的二进

序列化通俗地讲就是将一个对象转换成一个字节流的过程,这样就可以轻松保存在磁盘文件或数据库中。反序列化是序列化的逆过程,就是将一个字节流转换回原来的对象的过程。

session中可以保存任何值,从最简单的字符到最复杂的类都可以啊,不过还是建议尽量不要保存类,占用资源太多。 List <(Of <(T>)>) 类已经是序列化的类(基类就带[S

然而为什么需要序列化和反序列化这样的机制呢?这个问题也就涉及到序列化和反序列化的用途了,

"指纹签卡",      "MachineName": "象园店"    }  ]} 反序列化后

对于序列化的主要用途有: 将应用程序的状态保存在一个磁盘文件或数据库中,并在应用程序下次运行时恢复状态。例如, Asp.net 中利用序列化和反序列化来保存和恢复会话状态。 一组对象可以轻松复制到Windows 窗体的剪贴板中,再粘贴回同一个或者另一个应用程序。 将对象按值从一个应用程序域中发送到另一个程序域

这种情况的话。。。。 用xml文件交互更安全稳定吧~ 否则是不是要看.net和java的序列化实现是否一致?如果有一点儿不一致,就说不定出什么问题了~~~

如果你要反序列的话,必须要有你可以序列化的对象。 list那个明显不是你原始的对象。 建议构造标准类对象。 然后通过json专门的方法类来处理你的json数据。 推荐使用j

并且如果把对象序列化成内存中的字节流,就可以利用一些其他的技术来处理数据,例如,对数据进行加密和压缩等。

string jstr = "[{\\"custdate\\":\\"2012-02-07 18:43:11\\",\\"mobile\\":\\"13800000000\\",\\"mobilestatus\\":\\"1\\",\\&

二、序列化和反序列简单使用

js 字符串 转json    var json=JSON.parse("json字符串");或者 var json=eval("("+json字符串+")");

.Net Framework 提供二种序列化方式: 二进制序列化 XML 和SOAP序列化

1234567891011121314151617/// <summary>        /// 反序列化      &

如果你要反序列的话,必须要有你可以序列化的对象。 list那个明显不是你原始的对象。 建议构造标准类对象。 然后通过json专门的方法类来处理你的json数据。 推荐使用j

序列化和反序列化的简单使用:

在jsp中有个eval的,不知道可以运用不,用了次标签可以还原到开始的json状态,具体的我不知道这个东西怎么用。你看看,或许可以有收获。

using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;namespace Serializable{ [Serializable] public class Person { public string personName; [NonSerialized] public string personHeight; private int personAge; public int PersonAge { get { return personAge; } set { personAge = value; } } public void Write() { Console.WriteLine("Person Name: "+personName); Console.WriteLine("Person Height: " +personHeight); Console.WriteLine("Person Age: "+ personAge); } } class Program { static void Main(string[] args) { Person person = new Person(); person.personName = "Jerry"; person.personHeight = "175CM"; person.PersonAge = 22; Stream stream = Serialize(person); //为了演示,都重置 stream.Position = 0; person = null; person = Deserialize(stream); person.Write(); Console.Read(); } private static MemoryStream Serialize(Person person) { MemoryStream stream = new MemoryStream(); // 构造二进制序列化格式器 BinaryFormatter binaryFormatter = new BinaryFormatter(); // 告诉序列化器将对象序列化到一个流中 binaryFormatter.Serialize(stream, person); return stream; } private static Person Deserialize(Stream stream) { BinaryFormatter binaryFormatter = new BinaryFormatter(); return (Person)binaryFormatter.Deserialize(stream); } }}

你是不是要求到它的值,然后显示出来吧? 你可以这样 如果在javascript中就可以这样var $_josnObj= $.parseJOSN(jsonstr) 求到javascript对象,然后循环遍历它的值! var second

主要是调用System.Runtime.Serialization.Formatters.Binary命名空间下的BinnaryFormatter类来进行序列化和反序列化,调用反序列化后的结果截图:

js根据表单元素class属性,把表单元素的name和value组合为json格式;用表单元素class属性可以针对性地组合JSON数据。 2、后端ASP.NET用JavaScriptSerializer反序列化为对

从中可以看出除了标记NonSerialized的其他成员都能序列化,注意这个属性只能应用于一个类型中的字段,而且会被派生类型继承。

SOAP 和XML 的序列化和反序列化和上面类似,只需要改下格式化器就可以了, 这里我就不列出来了。

三、控制序列化和反序列化

有两种方式来实现控制序列化和反序列化: 通过OnSerializing, OnSerialized,OnDeserializing, OnDeserialized,NonSerialized和OptionalField等属性 实现System.Runtime.Serialization.ISerializable接口

如果你要反序列的话,必须要有你可以序列化的对象。 list那个明显不是你原始的对象。 建议构造标准类对象。 然后通过json专门的方法类来处理你的json数据。 推荐使用j

第一种方式实现控制序列化和反序列化代码:

using System;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;namespace ControlSerialization{ [Serializable] public class Circle { private double radius; //半径 [NonSerialized] public double area; //面积 public Circle(double inputradiu) { radius = inputradiu; area = Math.PI * radius * radius; } [OnDeserialized] private void OnDeserialized(StreamingContext context) { area = Math.PI * radius * radius; } public void Write() { Console.WriteLine("Radius is: " + radius); Console.WriteLine("Area is: " + area); } } class Program { static void Main(string[] args) { Circle c = new Circle(10); MemoryStream stream =new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); // 将对象序列化到内存流中,这里可以使用System.IO.Stream抽象类中派生的任何类型的一个对象, 这里我使用了 MemoryStream类型。 formatter.Serialize(stream,c); stream.Position = 0; c = null; c = (Circle)formatter.Deserialize(stream); c.Write(); Console.Read(); } }}

运行结果为:

注意:如果注释掉 OnDeserialized属性的话,area字段的值就是0了,因为area字段没有被序列化到流中。

在上面需要序列化的对象中,格式化器只会序列化对象的radius字段的值。area字段中的值不会序列化,因为该字段已经应用了NonSerializedAttribute属性,然后我们用Circle c=new Circle(10)这样代码构建一个Circle对象时,在内部,area会设置一个约为314.159这样的值,这个对象序列化时,只有radius的字段的值(10)写入流中, 但当反序列化成一个Circle对象时,它的area字段的值会初始化为0,而不是约314.159的一个值。为了解决这样的问题,所以自定义一个方法应用OnDeserializedAttribute属性。此时的执行过程为:每次反序列化类型的一个实例,格式化器都会检查类型中是否定义了 一个应用了该attribute的方法,如果是,就调用该方法,调用该方法时,所有可序列化的字段都会被正确设置。除了OnDeserializedAttribute这个定制attribute,system.Runtime.Serialization命名空间还定义了OnSerializingAttribute,OnSerializedAttribute和OnDeserializingAttribute这些定制属性。

实现ISerializable接口方式控制序列化和反序列化代码:

using System;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;using System.Security.Permissions;namespace ControlSerilization2{ [Serializable] public class MyObject : ISerializable { public int n1; public intn2; [NonSerialized] public String str; public MyObject() { } protected MyObject(SerializationInfo info, StreamingContext context) { n1 = info.GetInt32("i"); n2 = info.GetInt32("j"); str = info.GetString("k"); } [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("i", n1); info.AddValue("j", n2); info.AddValue("k", str); } public void Write() { Console.WriteLine("n1 is: " + n1); Console.WriteLine("n2 is: " + n2); Console.WriteLine("str is: " + str); } } class Program { static void Main(string[] args) { MyObject obj = new MyObject(); obj.n1 = 2; obj.n2 = 3; obj.str = "Jeffy"; MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); // 将对象序列化到内存流中,这里可以使用System.IO.Stream抽象类中派生的任何类型的一个对象, 这里我使用了 MemoryStream类型。 formatter.Serialize(stream, obj); stream.Position = 0; obj = null; obj = (MyObject)formatter.Deserialize(stream); obj.Write(); Console.Read(); } }}

结果为:

此时的执行过程为:当格式化器序列化对象时,会检查每个对象,如果发现一个对象的类型实现了ISerializable接口,格式化器会忽视所有定制属性,改为构造一个新的System.Runtime.Serialization.SerializationInfo对象,这个对象包含了要实际为对象序列化的值的集合。构造好并初始化好SerializationInfo对象后,格式化器调用类型的GetObjectData方法,并向它传递对SerializationInfo对象的引用,GetObjectData方法负责决定需要哪些信息来序列化对象,并将这些信息添加到SerializationInfo对象中,通过调用AddValue方法来添加需要的每个数据,添加好所有必要的序列化信息后,会返回至格式化器,然后格式化器获取已经添加到SerializationInfo对象中的所有值,并将它们都序列化到流中,当反序列化时,格式化器从流中提取一个对象时,会为新对象分配内存,最初,这个对象的所有字段都设为0或null,然后,格式化器检查类型是否实现了ISerializable接口,如果存在这个接口, 格式化器就尝试调用一个特殊构造器,它的参数和GetObjectData方法的完全一致。

四、格式化器如何序列化和反序列化

从上面的分析中可以看出,进行序列化和反序列化主要是格式化器在工作的,然而下面就是要讲讲格式化器是如何序列化一个应用了 SerializableAttribute 属性的对象。

    格式化器调用FormatterServices的GetSerializableMembers方法:public static MemberInfo[] GetSerializableMembers(Type type,StreamingContext context);这个方法利用发射获取类型的public和private实现字段(标记了NonSerializedAttributee属性的字段除外)。方法返回由MemberInfo对象构成的一个数组,其中每个元素对应于一个可序列化的实例字段。 对象被序列化,System.Reflection.MemberInfo对象数组传给FormatterServices的静态方法GetObjectData: public static object[] GetObjectData(Object obj,MemberInfo[] members); 这个方法返回一个Object数组,其中每个元素都标识了被序列化的那个对象中的一个字段的值。 格式化器将程序集标识和类型的完整名称写入流中。 格式化器然后遍历两个数组中的元素,将每个成员的名称和值写入流中。

接下来是解释格式化器如何自动反序列化一个应用了 SerializableAttribute属性的对象。

    格式化器从流中读取程序集标识和完整类型名称。 格式化器调用FormatterServices的静态方法GetUninitializedObject: public static Object GetUninitializedObject(Type ttype);这个方法为一个新对象分配内存,但不为对象调用构造器。然而,对象的所有字段都被初始化为0或null. 格式化器现在构造并初始化一个MemberInfo数组,调用FormatterServices的GetSerializableMembers方法,这个方法返回序列化好、现在需要反序列化的一组字段。 格式化器根据流中包含的数据创建并初始化一个Object数组。 将对新分配的对象、MemberInfo数组以及并行Object数组的引用传给FormatterServices的静态方法PopulateObjectMembers:

public static Object PopulateObjectMembers(Object obj,MemberInfo[] members,Object[] data);这个方法遍历数组,将每个字段初始化成对应的值。

注:格式化如何序列化和反序列对象部分摘自CLR via C#(第三版),写在这里可以让初学者进一步理解格式化器在序列化和反序列化过程中所做的工作。

写到这里这篇关于序列化和反序列的文章终于结束了, 希望对自己以后复习和园子里的朋友有帮助。

以上就是浅谈.Net中的序列化和反序列化的详细内容,更多关于.net 序列化和反序列化的资料请关注真格学网其它相关文章!

   对JSON数据进行序列化和反序列化   可以使用DataContractJsonSerializer类将类型实例序列化为JSON字符串,并将JSON字符串反序列化为类型实例。 DataContractJsonSerializer在System.Runtime.Serialization.Json命名空间下,.NET Framework 3.5包含在System.ServiceModel.Web.dll中,需要添加对其的引用;.NET Framework 4在System.Runtime.Serialization中。   方法一:引入System.Web.Script.Serialization命名空间使用 JavaScriptSerializer类实现简单的序列化序列化类:Personnel 代码如下   public class Personnel { public int Id { get; set; } public string Name { get; set; } }   执行序列化反序列化: 代码如下   protected void Page_Load(object sender, EventArgs e) { Personnel personnel = new Personnel(); personnel.Id = 1; personnel.Name = "小白"; JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); //执行序列化 string r1 = jsonSerializer.Serialize(personnel); //执行反序列化 Personnel _Personnel = jsonSerializer.Deserialize<Personnel>(r1); }     r1输出结果:{"Id":1,"Name":"小白"}   可以使用 ScriptIgnore属性标记不序列化公共属性或公共字段。 代码如下   public class Personnel { [ScriptIgnore] public int Id { get; set; } public string Name { get; set; } }   r1输出结果:{"Name":"小白"}   方法二:引入 System.Runtime.Serialization.Json命名空间使用 DataContractJsonSerializer类实现序列化   序列化类:People 代码如下     public class People { public int Id { get; set; } public string Name { get; set; } }   执行序列化反序列化 代码如下   protected void Page_Load(object sender, EventArgs e) { People people = new People(); people.Id = 1; people.Name = "小白"; DataContractJsonSerializer json = new DataContractJsonSerializer(people.GetType()); string szJson = ""; //序列化 using (MemoryStream stream = new MemoryStream()) { json.WriteObject(stream, people); szJson = Encoding.UTF8.GetString(stream.ToArray()); } //反序列化 using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(People)); People _people = (People)serializer.ReadObject(ms); } }     szJson输出结果:{"Id":1,"Name":"小白"}   可以使用IgnoreDataMember:指定该成员不是数据协定的一部分且没有进行序列化,DataMember:定义序列化属性参数,使用DataMember属性标记字段必须使用DataContract标记类 否则DataMember标记不起作用。 代码如下     [DataContract] public class People { [DataMember(Name = "id")] public int Id { get; set; } [IgnoreDataMember] public string Name { get; set; } }   输出结果: {"id":1}   JSON序列化和反序列化日期时间的处理   JSON格式不直接支持日期和时间。DateTime值值显示为“/Date(700000+0500)/”形式的JSON字符串,其中第一个数字(在提 供的示例中为 700000)是 GMT 时区中自 1970 年 1 月 1 日午夜以来按正常时间(非夏令时)经过的毫秒数。该数字可以是负数,以表示之前的时间。示例中包括“+0500”的部分可选,它指示该时间属于Local 类型,即它在反序列化时应转换为本地时区。如果没有该部分,则会将时间反序列化为Utc。   修改Person类,添加LastLoginTime: 代码如下   public class Person { public string Name { get; set; } public int Age { get; set; } public DateTime LastLoginTime { get; set; } } Person p = new Person(); p.Name = "张三"; p.Age = 28; p.LastLoginTime = DateTime.Now; string jsonString = JsonHelper.JsonSerializer<Person>(p);   序列化结果:   {"Age":28,"LastLoginTime":"/Date(1294499956278+0800)/","Name":"张三"}   1. 在后台使用正则表达式对其替换处理。修改JsonHelper: 代码如下   using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Runtime.Serialization.Json; using System.IO; using System.Text; using System.Text.RegularExpressions; /// <summary> /// JSON序列化和反序列化辅助类 /// </summary> public class JsonHelper { /// <summary> /// JSON序列化 /// </summary> public static string JsonSerializer<T>(T t) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, t); string jsonString = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); //替换Json的Date字符串 string p = @"/Date((d+)+d+)/"; MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString); Regex reg = new Regex(p); jsonString = reg.Replace(jsonString, matchEvaluator); return jsonString; } /// <summary> /// JSON反序列化 /// </summary> public static T JsonDeserialize<T>(string jsonString) { //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"/Date(1294499956278+0800)/"格式 string p = @"d{4}-d{2}-d{2}sd{2}:d{2}:d{2}"; MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate); Regex reg = new Regex(p); jsonString = reg.Replace(jsonString, matchEvaluator); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)ser.ReadObject(ms); return obj; } /// <summary> /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串 /// </summary> private static string ConvertJsonDateToDateString(Match m) { string result = string.Empty; DateTime dt = new DateTime(1970,1,1); dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value)); dt = dt.ToLocalTime(); result = dt.ToString("yyyy-MM-dd HH:mm:ss"); return result; } /// <summary> /// 将时间字符串转为Json时间 /// </summary> private static string ConvertDateStringToJsonDate(Match m) { string result = string.Empty; DateTime dt = DateTime.Parse(m.Groups[0].Value); dt = dt.ToUniversalTime(); TimeSpan ts = dt - DateTime.Parse("1970-01-01"); result = string.Format("/Date({0}+0800)/",ts.TotalMilliseconds); return result; } }   序列化Demo: 代码如下   Person p = new Person(); p.Name = "张三"; p.Age = 28; p.LastLoginTime = DateTime.Now; string jsonString = JsonHelper.JsonSerializer<Person>(p);   运行结果: 代码如下   {"Age":28,"LastLoginTime":"2011-01-09 01:00:56","Name":"张三"} 反序列化Demo: string json = "{"Age":28,"LastLoginTime":"2011-01-09 00:30:00","Name":"张三"}"; p=JsonHelper.JsonDeserialize<Person>(json);内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • c#使用json.net进行序列化和反序列化及定制化
  • .net中json的序列化和反序列化的几种方式
  • asp.net下使用xml反序列化、缓存依赖实现个性化配置文件的实时生效
  • .net中的序列化和反序列化详解
  • .net的序列化与反序列化实例
  • asp.net中json的序列化和反序列化使用说明
  • jquery 组合form元素为json格式,asp.net反序列化
  • asp.net 序列化and反序列化演示
  • asp.net xml序列化与反序列化
  • 生成代码从t到t1、t2、tn自动生成多个类型的泛型实例代码
  • asp.net下母版页和内容页中的事件发生顺序整理
  • asp.net网站首页根据ip自动跳转指定页面的示例
  • visualstudio2019中为.net core winform app启用窗体设计器
  • razor模板引擎简单介绍
  • asp.net core项目中如何使用html文件
  • 解决 the controls collection cannot be modified because the
  • 以ip来获取客户端电脑名称(一句代码实现)
  • asp.net操作excel的总结篇
  • asp.net(c#)程序版本升级更新的实现代码
  • asp.net JSON序列化与反序列化使用
  • asp.net json序列化与反序列化应用在什么地方?
  • 浅析JavaScriptSerializer类的序列化与反序列化
  • C# .Net Xml序列化与反序列化问题:Xml节点是动态的,不确定的...
  • VB.NET 如何反序列化通过百度翻译API获得的JSON字符串 高...
  • C#序列化和反序列化到底是什么意思?
  • asp.net序列化和反序列化的问题?
  • .net 反序列化出错
  • 可以用.net序列化然后用java反序列化吗?也就是说java和.net平...
  • .net 反序列化JSON字符串
  • .net 中 Json 反序列化问题
  • asp.net中反序列化一个数组,得到一个json字符串,在ajax中怎么...
  • net的Deserialize能反序列化微信公众平台post的XML吗
  • c++中的序列化与反序列化怎么实现的?
  • 在wp7上用JSON.NET反序列化json串时遇到了问题
  • .net 反序列化问题 当数据成员为固定数值时,这么办
  • Jquery 组合form元素为json格式,asp.net反序列化
  • NET Framework 4.0中序列化成JSON数据及JSON数据的反序列...
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础应用实用技巧自学过程首页asp.netc#使用json.net进行序列化和反序列化及定制化.net中json的序列化和反序列化的几种方式asp.net下使用xml反序列化、缓存依赖实现个性化配置文件的实时生效.net中的序列化和反序列化详解.net的序列化与反序列化实例asp.net中json的序列化和反序列化使用说明jquery 组合form元素为json格式,asp.net反序列化asp.net 序列化and反序列化演示asp.net xml序列化与反序列化生成代码从t到t1、t2、tn自动生成多个类型的泛型实例代码asp.net下母版页和内容页中的事件发生顺序整理asp.net网站首页根据ip自动跳转指定页面的示例visualstudio2019中为.net core winform app启用窗体设计器razor模板引擎简单介绍asp.net core项目中如何使用html文件解决 the controls collection cannot be modified because the 以ip来获取客户端电脑名称(一句代码实现)asp.net操作excel的总结篇asp.net(c#)程序版本升级更新的实现代码java正则表达式 pattern和matche未将对象引用设置到对象的实例 (asp.net(c#)网页跳转七种方法小结未能加载文件或程序集“xxx”或它asp.net“服务器应用程序不可用”asp.net中的几种弹出框提示基本实asp.net gridview 72般绝技asp.net生成excel并导出下载五种asp.net对路径"xxxxx"asp.net汉字转拼音和获取汉字首字手把手教你在.net中创建web服务实现方法asp.net+xml操作基类(修改,删除,新增,创建.net的ajax请求数据提交实例图析asp.net core引入grpc服务模板asp.net html文件上传标签gridview中点击checkbox选中一行来改变此在一个网站下再以虚拟目录的方式挂多个网asp.net自定义控件之加载层利用asp.net mvc和bootstrap快速搭建个人asp.net mvc自定义错误页面真的简单吗?
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved