C# Note4:XML序列化和反序列化(含加密解密等)
前言
在项目中,我们经常用到各种配置文件,比如xml文件、binary文件等等,这里主要根据实践经验介绍下xml文件的序列化和反序列化(毕竟最常用)。
实践背景:我要做一个用户管理功能,用户账号信息存储在xml/binary文件中,需要对其进行读写,而且为了不让用户修改,必须对其加密,当时想的有3种做法:
(1)实现读写xml配置文件,并将关键信息加密;
(2)实现读写binary配置文件,并将关键信息加密;
(3)直接对配置文件进行加密解密和读写,不管它所使用的文件格式是xml、binary或其它。
这三种做法我都实现了,不过经过最后manager的确认觉得采用第(3)种方法最好。
方法一:
(推荐:Load and save objects to XML using serialization 本方法参考其思路)
(1)在我们将对象序列化为XML之前,对象的类代码必须包含各种自定义元数据属性(例如,[XmlAttributeAttribute(DataType = " date "])告诉编译器类及其字段和/或属性可以被序列化。
using System;
using System.Xml.Serialization;
using System.Collections.ObjectModel; namespace XXX.GlobalTypes
{
/// <summary>
/// Save user account information
/// </summary>
[Serializable]
[XmlRoot("UserManagement")]
public class UserAccountInfo
{
private readonly Collection<UserInfo> _users = new Collection<UserInfo>(); [XmlElement("UserAccountInfo")]
public Collection<UserInfo> Users
{
get { return this._users; }
}
} [Serializable]
public class UserInfo
{ [XmlElement("UserName")]
public string UserName
{
get;
set;
} [XmlElement("UserPwd")]
public string UserPwd
{
get;
set;
} [XmlElement("UserRole")]
public ACCESS_LEVEL UserRole
{
get;
set;
} [XmlElement("Description")]
public string Description
{
get;
set;
}
} }
(2)封装XML序列化的类(其中作为样例,我加入了加密解密的参数tDESkey,在将数据对象保存到xml文件后进行加密,从xml文件中读取数据前先进行解密):
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml.Serialization; // For serialization of an object to an XML Document file.
using System.Runtime.Serialization.Formatters.Binary; // For serialization of an object to an XML Binary file.
using System.IO; // For reading/writing data to an XML file.
using System.IO.IsolatedStorage; // For accessing user isolated data. namespace XXX.Utilities.Common
{
/// <summary>
/// Serialization format types.
/// </summary>
public enum SerializedFormat
{
/// <summary>
/// Binary serialization format.
/// </summary>
Binary, /// <summary>
/// Document serialization format.
/// </summary>
Document
} /// <summary>
/// Facade to XML serialization and deserialization of strongly typed objects to/from an XML file.
///
/// References: XML Serialization at http://samples.gotdotnet.com/:
/// http://samples.gotdotnet.com/QuickStart/howto/default.aspx?url=/quickstart/howto/doc/xmlserialization/rwobjfromxml.aspx
/// </summary>
public static class ObjectXMLSerializer<T> where T : class // Specify that T must be a class.
{
#region Load methods /// <summary>
/// Loads an object from an XML file in Document format.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml");
/// </code>
/// </example>
/// <param name="path">Path of the file to load the object from.</param>
/// <returns>Object loaded from an XML file in Document format.</returns>
public static T Load(string path, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey);
return serializableObject;
} /// <summary>
/// Loads an object from an XML file using a specified serialized format.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml", SerializedFormat.Binary);
/// </code>
/// </example>
/// <param name="path">Path of the file to load the object from.</param>
/// <param name="serializedFormat">XML serialized format used to load the object.</param>
/// <returns>Object loaded from an XML file using the specified serialized format.</returns>
public static T Load(string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = null; switch (serializedFormat)
{
case SerializedFormat.Binary:
serializableObject = LoadFromBinaryFormat(path, null);
break; case SerializedFormat.Document:
default:
serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey);
break;
} return serializableObject;
} /// <summary>
/// Loads an object from an XML file in Document format, supplying extra data types to enable deserialization of custom types within the object.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml", new Type[] { typeof(MyCustomType) });
/// </code>
/// </example>
/// <param name="path">Path of the file to load the object from.</param>
/// <param name="extraTypes">Extra data types to enable deserialization of custom types within the object.</param>
/// <returns>Object loaded from an XML file in Document format.</returns>
public static T Load(string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = LoadFromDocumentFormat(extraTypes, path, null, tDESkey);
return serializableObject;
} /// <summary>
/// Loads an object from an XML file in Document format, located in a specified isolated storage area.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());
/// </code>
/// </example>
/// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
/// <returns>Object loaded from an XML file in Document format located in a specified isolated storage area.</returns>
public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
return serializableObject;
} /// <summary>
/// Loads an object from an XML file located in a specified isolated storage area, using a specified serialized format.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);
/// </code>
/// </example>
/// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
/// <param name="serializedFormat">XML serialized format used to load the object.</param>
/// <returns>Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format.</returns>
public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = null; switch (serializedFormat)
{
case SerializedFormat.Binary:
serializableObject = LoadFromBinaryFormat(fileName, isolatedStorageDirectory);
break; case SerializedFormat.Document:
default:
serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
break;
} return serializableObject;
} /// <summary>
/// Loads an object from an XML file in Document format, located in a specified isolated storage area, and supplying extra data types to enable deserialization of custom types within the object.
/// </summary>
/// <example>
/// <code>
/// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });
/// </code>
/// </example>
/// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
/// <param name="extraTypes">Extra data types to enable deserialization of custom types within the object.</param>
/// <returns>Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format.</returns>
public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
{
T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
return serializableObject;
} #endregion #region Save methods /// <summary>
/// Saves an object to an XML file in Document format.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml");
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="path">Path of the file to save the object to.</param>
public static void Save(T serializableObject, string path, TripleDESCryptoServiceProvider tDESkey)
{
SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);
} /// <summary>
/// Saves an object to an XML file using a specified serialized format.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml", SerializedFormat.Binary);
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="path">Path of the file to save the object to.</param>
/// <param name="serializedFormat">XML serialized format used to save the object.</param>
public static void Save(T serializableObject, string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
{
switch (serializedFormat)
{
case SerializedFormat.Binary:
SaveToBinaryFormat(serializableObject, path, null);
break; case SerializedFormat.Document:
default:
SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);
break;
}
} /// <summary>
/// Saves an object to an XML file in Document format, supplying extra data types to enable serialization of custom types within the object.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml", new Type[] { typeof(MyCustomType) });
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="path">Path of the file to save the object to.</param>
/// <param name="extraTypes">Extra data types to enable serialization of custom types within the object.</param>
public static void Save(T serializableObject, string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
{
SaveToDocumentFormat(serializableObject, extraTypes, path, null, tDESkey);
} /// <summary>
/// Saves an object to an XML file in Document format, located in a specified isolated storage area.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)
{
SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
} /// <summary>
/// Saves an object to an XML file located in a specified isolated storage area, using a specified serialized format.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
/// <param name="serializedFormat">XML serialized format used to save the object.</param>
public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
{
switch (serializedFormat)
{
case SerializedFormat.Binary:
SaveToBinaryFormat(serializableObject, fileName, isolatedStorageDirectory);
break; case SerializedFormat.Document:
default:
SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
break;
}
} /// <summary>
/// Saves an object to an XML file in Document format, located in a specified isolated storage area, and supplying extra data types to enable serialization of custom types within the object.
/// </summary>
/// <example>
/// <code>
/// SerializableObject serializableObject = new SerializableObject();
///
/// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });
/// </code>
/// </example>
/// <param name="serializableObject">Serializable object to be saved to file.</param>
/// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
/// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
/// <param name="extraTypes">Extra data types to enable serialization of custom types within the object.</param>
public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
{
SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
} #endregion #region Private private static FileStream CreateFileStream(IsolatedStorageFile isolatedStorageFolder, string path)
{
FileStream fileStream = null; if (isolatedStorageFolder == null)
fileStream = new FileStream(path, FileMode.OpenOrCreate);
else
fileStream = new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder); return fileStream;
} private static T LoadFromBinaryFormat(string path, IsolatedStorageFile isolatedStorageFolder)
{
T serializableObject = null; using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
serializableObject = binaryFormatter.Deserialize(fileStream) as T;
} return serializableObject;
} private static T LoadFromDocumentFormat(System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)
{
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.PreserveWhitespace = true; xmlDoc.Load(path);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
} // Decrypt the "UserManagement" element.
EncryptXml.Decrypt(xmlDoc, tDESkey);
xmlDoc.Save(path); T serializableObject = null; using (TextReader textReader = CreateTextReader(isolatedStorageFolder, path))
{
XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
serializableObject = xmlSerializer.Deserialize(textReader) as T;
} EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey);
xmlDoc.Save(path); return serializableObject;
} private static TextReader CreateTextReader(IsolatedStorageFile isolatedStorageFolder, string path)
{
TextReader textReader = null; if (isolatedStorageFolder == null)
textReader = new StreamReader(path);
else
textReader = new StreamReader(new IsolatedStorageFileStream(path, FileMode.Open, isolatedStorageFolder)); return textReader;
} private static TextWriter CreateTextWriter(IsolatedStorageFile isolatedStorageFolder, string path)
{
TextWriter textWriter = null; if (isolatedStorageFolder == null)
textWriter = new StreamWriter(path);
else
textWriter = new StreamWriter(new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder)); return textWriter;
} private static XmlSerializer CreateXmlSerializer(System.Type[] extraTypes)
{
Type ObjectType = typeof(T); XmlSerializer xmlSerializer = null; if (extraTypes != null)
xmlSerializer = new XmlSerializer(ObjectType, extraTypes);
else
xmlSerializer = new XmlSerializer(ObjectType); return xmlSerializer;
} private static void SaveToDocumentFormat(T serializableObject, System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)
{
using (TextWriter textWriter = CreateTextWriter(isolatedStorageFolder, path))
{
XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
xmlSerializer.Serialize(textWriter, serializableObject); textWriter.Close(); XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.PreserveWhitespace = true; xmlDoc.Load(path);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
} EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey); xmlDoc.Save(path);
}
} private static void SaveToBinaryFormat(T serializableObject, string path, IsolatedStorageFile isolatedStorageFolder)
{
using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(fileStream, serializableObject);
}
} #endregion
}
}
(3)Saving an object to an XML file/Loading an object from an XML file
// Load the userManagement object from the XML file using our UserAccountInfo class...
UserAccountInfo userManagement =ObjectXMLSerializer<UserAccountInfo>.Load(path, tDESkey); // Load the userManagement object from the XML file using our userManagement class...
ObjectXMLSerializer<UserAccountInfo>.Save(usermanagement, XML_FILE_NAME, tDESkey);
方法二:
其实,要想仅仅实现xml的序列化和反序列化还是很简单的,作为常用的类,可以很简单地将其实现为公共类:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization; namespace XXX.Common
{
public static class XmlHelper
{
public static object DeserializeObject<T>(string filePath)
{
try
{
var xs = new XmlSerializer(typeof(T));
using (var fs = new FileStream(filePath, FileMode.Open))
{
var reader = XmlReader.Create(fs);
return xs.Deserialize(reader);
}
}
catch (Exception exp)
{
throw new XmlException($"Failed in XML Deserialization {filePath}", exp);
}
} public static void SerializeObject<T>(string filePath, T o)
{
try
{
var x = new XmlSerializer(typeof(T));
using (var fs = new FileStream(filePath, FileMode.Create))
{
var writer = XmlWriter.Create(fs);
x.Serialize(writer, o);
}
}
catch (Exception exp)
{
throw new XmlException($"Failed in XML Serialization {filePath}", exp);
}
}
}
}
另可参考文章:
1.XML序列化和反序列化
C# Note4:XML序列化和反序列化(含加密解密等)的更多相关文章
- 第四节:IO、序列化和反序列化、加密解密技术
一. IO读写 这里主要包括文件的读.写.移动.复制.删除.文件夹的创建.文件夹的删除等常规操作. 注意:这里需要特别注意,对于普通的控制台程序和Web程序,将"相对路径"转换成& ...
- C# UTF8的BOM导致XML序列化与反序列化报错:Data at the root level is invalid. Line 1, position 1.
最近在写一个xml序列化及反序列化实现时碰到个问题,大致类似下面的代码: class Program { static void Main1(string[] args) { var test = n ...
- XML 序列化与反序列化
XML序列化与反序列化 1.将一个类转化为XML文件 /// <summary> /// 对象序列化成XML文件 /// </summary> /// <param na ...
- XmlSerializer 对象的Xml序列化和反序列化
http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html 这篇随笔对应的.Net命名空间是System.Xm ...
- C#的XML序列化及反序列化
webservice在工作中用到的很多,基本都是以XML格式问通讯内容,其中最关键的就是XML串的序列化及反序列化. XML的运用中有两种信息传递,一种为XML的请求信息,另一种为返回信息,要运用XM ...
- .NET XML序列化与反序列化
闲着没事,写了两个通用的XML序列化与反序列化的方法. 贴出来当作笔记吧! /// <summary> /// XML序列化 /// </summary> /// <ty ...
- XmlSerializer 对象的Xml序列化和反序列化,XMLROOT别名设置
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中 ...
- c# XML序列化与反序列化
c# XML序列化与反序列化 原先一直用BinaryFormatter来序列化挺好,可是最近发现在WinCE下是没有办法进行BinaryFormatter操作,很不爽,只能改成了BinaryWrite ...
- Xml序列化、反序列化帮助类
之前从网络上找了一个Xml处理帮助类,并整理了一下,这个帮助类针对Object类型进行序列化和反序列化,而不需要提前定义Xml的结构,把它放在这儿供以后使用 /// <summary> / ...
随机推荐
- 数位dp D - Count The Bits
题目:D - Count The Bits 博客 #include <cstdio> #include <cstring> #include <cstdlib> # ...
- 1.02-get-params
import urllib.request import urllib.parse import string def get_method_params(): url = "http:// ...
- Android真机调试不打印日志解决方式
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/RowandJJ/article/details/24543459 1.在拨号界面输入:*#*#28 ...
- [TJOI2017]城市
嘟嘟嘟 这题刚开始想复杂了,想什么dp去了,其实没那么难. 考虑断掉一条边,记分离出来的两棵子树为A和B,那么合并后的树的直径可能有三种情况: 1.A的直径. 2.B的直径 3.A的半径+边权+B的半 ...
- Linux:Day11(上) ifcfg命令
将Linux主机接入到网络中: 配置方式: 静态指定: ifcfg:ifconfig,route,netstat ip:object{link,addr,route},ss,tc 配置文件:syste ...
- Python:Day20 模块
模块是用来组织函数的. 模块一共3种: python标准库 第三方模块 应用程序自定义模块 模块搜索路径:sys.path import sys print(sys.path) import calc ...
- 转载 1-EasyNetQ介绍(黄亮翻译) https://www.cnblogs.com/HuangLiang/p/7105659.html
EasyNetQ 是一个容易使用,坚固的,针对RabbitMQ的 .NET API. 假如你尽可能快的想去安装和运行RabbitMQ,请去看入门指南.EasyNetQ是为了提供一个尽可能简洁的适用与R ...
- EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...
- Java多线程编程核心技术(一)Java多线程技能
1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
- 面试 9:Java 玩转冒泡排序
面试 9:用 Java 实现冒泡排序 南尘的朋友们,新的一周好,原本打算继续讲链表考点算法的,这里姑且是卡一段.虽然在我们 Android 开发中,很少涉及到排序算法,因为基本官方都帮我们封装好了,但 ...