A grande richiesta condivido un piccolo helper, realizzato ormai diversi anni orsono, che ancora utilizzo quando ho bisogno di effettuare operazioni di Serialize/Deserialize di oggetti POCO in C#: i formati supportati al momento sono XML e JSON, ovvero i più diffusi e utilizzati in ambito web, ma è possibile estenderla anche ad altri.
Come potrete vedere si tratta di una semplice classe statica che include una serie di "coppie di metodi" per la serializzazione e deserializzazione corrispondente: il primo elemento di ciascuna coppia - quello che si occupa della serializzazione di un oggetto T - è stato implementato in modo tale da poter essere utilizzato anche come extension method, ovvero partendo direttamente dall'oggetto che si desidera serializzare. Può essere utilizzata all'interno di qualsiasi libreria di classi o anche direttamente inclusa in un progetto Web Forms, Windows Forms, MVC, WebAPI, .NET Core o di qualsiasi altro tipo.
Questo l'elenco dei metodi attualmente implementati:
- SerializeObject / DeserializeObject
- SerializeObjectUsingBinaryFormatter / DeserializeObjectUsingBinaryFormatter
- SerializeToXML / DeserializeFromXML
- SerializeToJson / DeserializeFromJson
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
using System; using System.Text; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Xml; using System.Xml.Serialization; using System.Web.Script.Serialization; namespace Ryadel.Components.Serialization { /// <summary> /// Helper class to serialize/deserialize any [Serializable] object in a centralized way. /// </summary> public static class SerializationHelper { /// <summary> /// Internal utility method to convert an UTF8 Byte Array to an UTF8 string. /// </summary> /// <param name="characters"></param> /// <returns></returns> private static string UTF8ByteArrayToString(byte[] characters) { return new UTF8Encoding().GetString(characters); } /// <summary> /// Internal utility method to convert an UTF8 string to an UTF8 Byte Array. /// </summary> /// <param name="xml"></param> /// <returns></returns> private static byte[] StringToUTF8ByteArray(string xml) { return new UTF8Encoding().GetBytes(xml); } /// <summary> /// Serialize a [Serializable] object of type T into an XML/UTF8 string. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="item"></param> /// <returns></returns> public static string SerializeObject<T>(this T item) { try { using (MemoryStream stream = new MemoryStream()) { using (XmlTextWriter xml = new XmlTextWriter(stream, new UTF8Encoding(false))) { XmlSerializer xs = new XmlSerializer(typeof(T)); xs.Serialize(xml, item); return UTF8ByteArrayToString(((MemoryStream)xml.BaseStream).ToArray()); } } } catch (Exception) { return string.Empty; } } /// <summary> /// De-serialize an XML/UTF8 string into an object of type T. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="xml"></param> /// <returns></returns> public static T DeserializeObject<T>(string xml) { using (MemoryStream stream = new MemoryStream(StringToUTF8ByteArray(xml))) using (new XmlTextWriter(stream, new UTF8Encoding(false))) { return (T)new XmlSerializer(typeof(T)).Deserialize(stream); } } /// <summary> /// Serialize an object T using BinaryFormatter. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="item"></param> /// <returns></returns> public static string SerializeObjectUsingBinaryFormatter<T>(this T item) { BinaryFormatter serializer = new BinaryFormatter(); using (MemoryStream ms = new MemoryStream()) { serializer.Serialize(ms, item); return UTF8ByteArrayToString(ms.ToArray()); } } /// <summary> /// De-serialize a BinaryFormatter-serialized string into an object of type T. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="str"></param> /// <returns></returns> public static T DeserializeObjectUsingBinaryFormatter<T>(string str) { BinaryFormatter serializer = new BinaryFormatter(); using (MemoryStream ms = new MemoryStream(StringToUTF8ByteArray(str))) { return (T)serializer.Deserialize(ms); } } /// <summary> /// Serialize a [Serializable] object of type T into an XML-formatted string using XmlSerializer /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">any T object</param> /// <returns>an XML-formatted string</returns> public static string SerializeToXML<T>(this T value) { if (value == null) { return string.Empty; } try { var xmlserializer = new XmlSerializer(typeof(T)); var stringWriter = new StringWriter(); using (var writer = XmlWriter.Create(stringWriter)) { xmlserializer.Serialize(writer, value); return stringWriter.ToString(); } } catch (Exception ex) { throw new Exception("An error occurred", ex); } } /// <summary> /// De-serialize a [Serializable] object of type T into an XML-formatted string using XmlSerializer /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">any T object</param> /// <returns>an XML-formatted string</returns> public static T DeserializeFromXML<T>(string xml) { if (String.IsNullOrEmpty(xml)) throw new NotSupportedException("ERROR: input string cannot be null."); try { var xmlserializer = new XmlSerializer(typeof(T)); var stringReader = new StringReader(xml); using (var reader = XmlReader.Create(stringReader)) { return (T)xmlserializer.Deserialize(reader); } } catch (Exception ex) { throw new Exception("An error occurred", ex); } } /// <summary> /// Serialize a [Serializable] object into a JSON-formatted string using System.Web.Script.Serialization.JavaScriptSerializer /// NOTE: you need to add a reference to System.Web.Extensions to have access to System.Web.Script.Serialization namespace. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">any T object</param> /// <returns>a JSON-formatted string</returns> public static string SerializeToJson<T>(this T value) { if (value == null) { return string.Empty; } try { return new JavaScriptSerializer().Serialize(value); } catch (Exception ex) { throw new Exception("An error occurred", ex); } } /// <summary> /// De-serialize a [Serializable] object into a JSON-formatted string using System.Web.Script.Serialization.JavaScriptSerializer /// NOTE: you need to add a reference to System.Web.Extensions to have access to System.Web.Script.Serialization namespace. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">any T object</param> /// <returns>a JSON-formatted string</returns> public static T DeserializeFromJson<T>(string json) { if (String.IsNullOrEmpty(json)) throw new NotSupportedException("ERROR: input string cannot be null."); try { return new JavaScriptSerializer().Deserialize<T>(json); } catch (Exception ex) { throw new Exception("An error occurred", ex); } } } } |
Inutile dire che, affinché il Serialize funzioni correttamente, gli oggetti devono essere di tipo [Serializable] e contenere unicamente proprietà che siano "serializzabili" a loro volta.
Per il momento è tutto: buona (de)serializzazione!