• 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文件中读取数据前先进行解密):

      1 using System;
      2 using System.Xml;
      3 using System.Security.Cryptography;
      4 using System.Security.Cryptography.Xml;
      5 using System.Xml.Serialization;     // For serialization of an object to an XML Document file.
      6 using System.Runtime.Serialization.Formatters.Binary; // For serialization of an object to an XML Binary file.
      7 using System.IO;                 // For reading/writing data to an XML file.
      8 using System.IO.IsolatedStorage; // For accessing user isolated data.
      9 
     10 namespace XXX.Utilities.Common
     11 {
     12     /// <summary>
     13     /// Serialization format types.
     14     /// </summary>
     15     public enum SerializedFormat
     16     {
     17         /// <summary>
     18         /// Binary serialization format.
     19         /// </summary>
     20         Binary,
     21 
     22         /// <summary>
     23         /// Document serialization format.
     24         /// </summary>
     25         Document
     26     }
     27 
     28 
     29     /// <summary>
     30     /// Facade to XML serialization and deserialization of strongly typed objects to/from an XML file.
     31     /// 
     32     /// References: XML Serialization at http://samples.gotdotnet.com/:
     33     /// http://samples.gotdotnet.com/QuickStart/howto/default.aspx?url=/quickstart/howto/doc/xmlserialization/rwobjfromxml.aspx
     34     /// </summary>
     35     public static class ObjectXMLSerializer<T> where T : class // Specify that T must be a class.
     36     {
     37         #region Load methods
     38 
     39         /// <summary>
     40         /// Loads an object from an XML file in Document format.
     41         /// </summary>
     42         /// <example>
     43         /// <code>
     44         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load(@"C:XMLObjects.xml");
     45         /// </code>
     46         /// </example>
     47         /// <param name="path">Path of the file to load the object from.</param>
     48         /// <returns>Object loaded from an XML file in Document format.</returns>
     49         public static T Load(string path, TripleDESCryptoServiceProvider tDESkey)
     50         {
     51             T serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey);
     52             return serializableObject;
     53         }
     54 
     55         /// <summary>
     56         /// Loads an object from an XML file using a specified serialized format.
     57         /// </summary>
     58         /// <example>
     59         /// <code>
     60         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load(@"C:XMLObjects.xml", SerializedFormat.Binary);
     61         /// </code>
     62         /// </example>        
     63         /// <param name="path">Path of the file to load the object from.</param>
     64         /// <param name="serializedFormat">XML serialized format used to load the object.</param>
     65         /// <returns>Object loaded from an XML file using the specified serialized format.</returns>
     66         public static T Load(string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
     67         {
     68             T serializableObject = null;
     69 
     70             switch (serializedFormat)
     71             {
     72                 case SerializedFormat.Binary:
     73                     serializableObject = LoadFromBinaryFormat(path, null);
     74                     break;
     75 
     76                 case SerializedFormat.Document:
     77                 default:
     78                     serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey);
     79                     break;
     80             }
     81 
     82             return serializableObject;
     83         }
     84 
     85         /// <summary>
     86         /// Loads an object from an XML file in Document format, supplying extra data types to enable deserialization of custom types within the object.
     87         /// </summary>
     88         /// <example>
     89         /// <code>
     90         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load(@"C:XMLObjects.xml", new Type[] { typeof(MyCustomType) });
     91         /// </code>
     92         /// </example>
     93         /// <param name="path">Path of the file to load the object from.</param>
     94         /// <param name="extraTypes">Extra data types to enable deserialization of custom types within the object.</param>
     95         /// <returns>Object loaded from an XML file in Document format.</returns>
     96         public static T Load(string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
     97         {
     98             T serializableObject = LoadFromDocumentFormat(extraTypes, path, null, tDESkey);
     99             return serializableObject;
    100         }
    101 
    102         /// <summary>
    103         /// Loads an object from an XML file in Document format, located in a specified isolated storage area.
    104         /// </summary>
    105         /// <example>
    106         /// <code>
    107         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());
    108         /// </code>
    109         /// </example>
    110         /// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
    111         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
    112         /// <returns>Object loaded from an XML file in Document format located in a specified isolated storage area.</returns>
    113         public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)
    114         {
    115             T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
    116             return serializableObject;
    117         }
    118 
    119         /// <summary>
    120         /// Loads an object from an XML file located in a specified isolated storage area, using a specified serialized format.
    121         /// </summary>
    122         /// <example>
    123         /// <code>
    124         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);
    125         /// </code>
    126         /// </example>        
    127         /// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
    128         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
    129         /// <param name="serializedFormat">XML serialized format used to load the object.</param>        
    130         /// <returns>Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format.</returns>
    131         public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
    132         {
    133             T serializableObject = null;
    134 
    135             switch (serializedFormat)
    136             {
    137                 case SerializedFormat.Binary:
    138                     serializableObject = LoadFromBinaryFormat(fileName, isolatedStorageDirectory);
    139                     break;
    140 
    141                 case SerializedFormat.Document:
    142                 default:
    143                     serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
    144                     break;
    145             }
    146 
    147             return serializableObject;
    148         }
    149 
    150         /// <summary>
    151         /// 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.
    152         /// </summary>
    153         /// <example>
    154         /// <code>
    155         /// serializableObject = ObjectXMLSerializer&lt;SerializableObject&gt;.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });
    156         /// </code>
    157         /// </example>        
    158         /// <param name="fileName">Name of the file in the isolated storage area to load the object from.</param>
    159         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to load the object from.</param>
    160         /// <param name="extraTypes">Extra data types to enable deserialization of custom types within the object.</param>
    161         /// <returns>Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format.</returns>
    162         public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
    163         {
    164             T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);
    165             return serializableObject;
    166         }
    167 
    168         #endregion
    169 
    170         #region Save methods
    171 
    172         /// <summary>
    173         /// Saves an object to an XML file in Document format.
    174         /// </summary>
    175         /// <example>
    176         /// <code>        
    177         /// SerializableObject serializableObject = new SerializableObject();
    178         /// 
    179         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, @"C:XMLObjects.xml");
    180         /// </code>
    181         /// </example>
    182         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    183         /// <param name="path">Path of the file to save the object to.</param>
    184         public static void Save(T serializableObject, string path, TripleDESCryptoServiceProvider tDESkey)
    185         {
    186             SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);
    187         }
    188 
    189         /// <summary>
    190         /// Saves an object to an XML file using a specified serialized format.
    191         /// </summary>
    192         /// <example>
    193         /// <code>
    194         /// SerializableObject serializableObject = new SerializableObject();
    195         /// 
    196         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, @"C:XMLObjects.xml", SerializedFormat.Binary);
    197         /// </code>
    198         /// </example>
    199         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    200         /// <param name="path">Path of the file to save the object to.</param>
    201         /// <param name="serializedFormat">XML serialized format used to save the object.</param>
    202         public static void Save(T serializableObject, string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
    203         {
    204             switch (serializedFormat)
    205             {
    206                 case SerializedFormat.Binary:
    207                     SaveToBinaryFormat(serializableObject, path, null);
    208                     break;
    209 
    210                 case SerializedFormat.Document:
    211                 default:
    212                     SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);
    213                     break;
    214             }
    215         }
    216 
    217         /// <summary>
    218         /// Saves an object to an XML file in Document format, supplying extra data types to enable serialization of custom types within the object.
    219         /// </summary>
    220         /// <example>
    221         /// <code>        
    222         /// SerializableObject serializableObject = new SerializableObject();
    223         /// 
    224         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, @"C:XMLObjects.xml", new Type[] { typeof(MyCustomType) });
    225         /// </code>
    226         /// </example>
    227         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    228         /// <param name="path">Path of the file to save the object to.</param>
    229         /// <param name="extraTypes">Extra data types to enable serialization of custom types within the object.</param>
    230         public static void Save(T serializableObject, string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
    231         {
    232             SaveToDocumentFormat(serializableObject, extraTypes, path, null, tDESkey);
    233         }
    234 
    235         /// <summary>
    236         /// Saves an object to an XML file in Document format, located in a specified isolated storage area.
    237         /// </summary>
    238         /// <example>
    239         /// <code>        
    240         /// SerializableObject serializableObject = new SerializableObject();
    241         /// 
    242         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());
    243         /// </code>
    244         /// </example>
    245         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    246         /// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
    247         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
    248         public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)
    249         {
    250             SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
    251         }
    252 
    253         /// <summary>
    254         /// Saves an object to an XML file located in a specified isolated storage area, using a specified serialized format.
    255         /// </summary>
    256         /// <example>
    257         /// <code>        
    258         /// SerializableObject serializableObject = new SerializableObject();
    259         /// 
    260         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);
    261         /// </code>
    262         /// </example>
    263         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    264         /// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
    265         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
    266         /// <param name="serializedFormat">XML serialized format used to save the object.</param>        
    267         public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)
    268         {
    269             switch (serializedFormat)
    270             {
    271                 case SerializedFormat.Binary:
    272                     SaveToBinaryFormat(serializableObject, fileName, isolatedStorageDirectory);
    273                     break;
    274 
    275                 case SerializedFormat.Document:
    276                 default:
    277                     SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
    278                     break;
    279             }
    280         }
    281 
    282         /// <summary>
    283         /// 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.
    284         /// </summary>
    285         /// <example>
    286         /// <code>
    287         /// SerializableObject serializableObject = new SerializableObject();
    288         /// 
    289         /// ObjectXMLSerializer&lt;SerializableObject&gt;.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });
    290         /// </code>
    291         /// </example>        
    292         /// <param name="serializableObject">Serializable object to be saved to file.</param>
    293         /// <param name="fileName">Name of the file in the isolated storage area to save the object to.</param>
    294         /// <param name="isolatedStorageDirectory">Isolated storage area directory containing the XML file to save the object to.</param>
    295         /// <param name="extraTypes">Extra data types to enable serialization of custom types within the object.</param>
    296         public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)
    297         {
    298             SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);
    299         }
    300 
    301         #endregion
    302 
    303         #region Private
    304 
    305         private static FileStream CreateFileStream(IsolatedStorageFile isolatedStorageFolder, string path)
    306         {
    307             FileStream fileStream = null;
    308 
    309             if (isolatedStorageFolder == null)
    310                 fileStream = new FileStream(path, FileMode.OpenOrCreate);
    311             else
    312                 fileStream = new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder);
    313 
    314             return fileStream;
    315         }
    316 
    317         private static T LoadFromBinaryFormat(string path, IsolatedStorageFile isolatedStorageFolder)
    318         {
    319             T serializableObject = null;
    320 
    321             using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))
    322             {
    323                 BinaryFormatter binaryFormatter = new BinaryFormatter();
    324                 serializableObject = binaryFormatter.Deserialize(fileStream) as T;
    325             }
    326 
    327             return serializableObject;
    328         }
    329 
    330         private static T LoadFromDocumentFormat(System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)
    331         {
    332             XmlDocument xmlDoc = new XmlDocument();
    333             try
    334             {
    335                 xmlDoc.PreserveWhitespace = true;
    336 
    337                 xmlDoc.Load(path);
    338             }
    339             catch (Exception e)
    340             {
    341                 Console.WriteLine(e.Message);
    342             }
    343 
    344             // Decrypt the "UserManagement" element.
    345             EncryptXml.Decrypt(xmlDoc, tDESkey);
    346             xmlDoc.Save(path);
    347 
    348             T serializableObject = null;
    349 
    350             using (TextReader textReader = CreateTextReader(isolatedStorageFolder, path))
    351             {
    352                 XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
    353                 serializableObject = xmlSerializer.Deserialize(textReader) as T;
    354             }
    355 
    356             EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey);
    357             xmlDoc.Save(path);
    358 
    359             return serializableObject;
    360         }
    361 
    362         private static TextReader CreateTextReader(IsolatedStorageFile isolatedStorageFolder, string path)
    363         {
    364             TextReader textReader = null;
    365 
    366             if (isolatedStorageFolder == null)
    367                 textReader = new StreamReader(path);
    368             else
    369                 textReader = new StreamReader(new IsolatedStorageFileStream(path, FileMode.Open, isolatedStorageFolder));
    370 
    371             return textReader;
    372         }
    373 
    374         private static TextWriter CreateTextWriter(IsolatedStorageFile isolatedStorageFolder, string path)
    375         {
    376             TextWriter textWriter = null;
    377 
    378             if (isolatedStorageFolder == null)
    379                 textWriter = new StreamWriter(path);
    380             else
    381                 textWriter = new StreamWriter(new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder));
    382 
    383             return textWriter;
    384         }
    385 
    386         private static XmlSerializer CreateXmlSerializer(System.Type[] extraTypes)
    387         {
    388             Type ObjectType = typeof(T);
    389 
    390             XmlSerializer xmlSerializer = null;
    391 
    392             if (extraTypes != null)
    393                 xmlSerializer = new XmlSerializer(ObjectType, extraTypes);
    394             else
    395                 xmlSerializer = new XmlSerializer(ObjectType);
    396 
    397             return xmlSerializer;
    398         }
    399 
    400         private static void SaveToDocumentFormat(T serializableObject, System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)
    401         {
    402             using (TextWriter textWriter = CreateTextWriter(isolatedStorageFolder, path))
    403             {
    404                 XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
    405                 xmlSerializer.Serialize(textWriter, serializableObject);
    406 
    407                 textWriter.Close();
    408 
    409                 XmlDocument xmlDoc = new XmlDocument();
    410                 try
    411                 {
    412                     xmlDoc.PreserveWhitespace = true;
    413 
    414                     xmlDoc.Load(path);
    415                 }
    416                 catch (Exception e)
    417                 {
    418                     Console.WriteLine(e.Message);
    419                 }
    420 
    421                 EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey);
    422 
    423                 xmlDoc.Save(path);
    424             }
    425         }
    426 
    427         private static void SaveToBinaryFormat(T serializableObject, string path, IsolatedStorageFile isolatedStorageFolder)
    428         {
    429             using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))
    430             {
    431                 BinaryFormatter binaryFormatter = new BinaryFormatter();
    432                 binaryFormatter.Serialize(fileStream, serializableObject);
    433             }
    434         }
    435 
    436         
    437         #endregion
    438     }
    439 }

    (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序列化和反序列化

    2.在.net中读写config文件的各种方法

  • 相关阅读:
    js1
    curl获取图片
    TP中讲的两种ajax方法
    tp验证码
    TP上传图片
    TP中登录验证
    tp中自定义跳转页面
    用户数据库表状态一类的问题
    用php实现斐波那契数列
    微信的网页授权登陆
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/6870149.html
Copyright © 2020-2023  润新知