Objects to/from XML: generic Load and Save [duplicate] - c#

This question already has answers here:
How to save/restore serializable object to/from file?
(6 answers)
Closed 8 years ago.
I need to store some objects as XML files in order to save data and load it later.
I coded this and it works for me:
public static Project Load(String file)
{
using (var stream = System.IO.File.OpenRead(file))
{
var serializer = new XmlSerializer(typeof(Project));
return serializer.Deserialize(stream) as Project;
}
}
public static void Save(Project p, String file)
{
using (var writer = new System.IO.StreamWriter(file))
{
var serializer = new XmlSerializer(p.GetType());
serializer.Serialize(writer, p);
writer.Flush();
}
}
Now, I need to do this with other kind of objects and I don't really want to copy/paste these methods for every object class.
Is possible to pass the object class to methods and make these methods generic for any object class?

i usually use this both methods from https://stackoverflow.com/a/271423/1315444
hope this helps :D
/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
if (xml == null) throw new ArgumentNullException("xml");
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xml))
{
try { return (T)serializer.Deserialize(reader); }
catch { return null; } // Could not be deserialized to this type.
}
}
then you can go with
Project p = new Project();
string result = p.XmlSerialize();
Project p2 = result.XmlDeserialize<Project>();

Related

XML Serializing and Deserializing List Data in Android App

So I am trying to deserialize and serialize a List.
The issue: The list(list1) is not saving to the file called "ListData" which should be created if not already there, into the documents folder in the android internal storage.
I think the file may not be creating properly or something, or the filepath is incorrect. Below is how it should be functioning but that isn't working as explained with the issue above.
I want to save the filename as something like "ListData".
Also, needs to be saved into the Internal Storage somewhere such as the Data folder of the app or Documents in internal storage.
The following is what i have for the code, but I can't seem to find any help elsewhere to fix my issue. It doesn't work, any ideas for a solution to what I want it to do?
Code:
public abstract class DataHandler
{
public static void SaveLists()
{
string filePath = Android.OS.Environment.DirectoryDocuments;
string fileName = "ListData";
XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
Stream writer = new FileStream(filePath, FileMode.Create);
serializer.Serialize(writer, _LISTFROMANOTHERCLASS_);
writer.Close();
}
public static void LoadLists()
{
string filePath = Android.OS.Environment.DirectoryDocuments;
string fileName = "ListData";
XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
Stream reader = new FileStream(filePath, FileMode.Open);
List<Item> list1 = new List<Item>();
list1 = (List<Item>) serializer.Deserialize(reader);
_LISTFROMANOTHERCLASS_ = list1;
reader.Close();
}
}
Hi I have written a class to do these but with JSON serlization check is it helps it uses MVVM Cross, It has code written to encrypt and decrypt data you can avoid these parts
public class PersistantStorageHelper<T>
{
IMvxFileStoreAsync _mvxFileStoreAsync;
IMvxFileStore _mvxFileStore;
EDEngine bcEngine = new EDEngine(new AesEngine(), Encoding.UTF8);
string currentkey_temp_dev = "AthulHarikumar00";//This static key is not being used it is a just a place holder
public PersistantStorageHelper() {
this._mvxFileStore = Mvx.Resolve<IMvxFileStore>();
this._mvxFileStoreAsync = Mvx.Resolve<IMvxFileStoreAsync>();
bcEngine.SetPadding(new Pkcs7Padding());
currentkey_temp_dev = Constants.PassPhrase.Substring(4, 12)+"Road";
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public async Task<T> GetPersistantObject(T obj)
{
var fileName = (typeof(T).ToString().Replace(".", "_"));
var x= await GetPersistantObject(obj, fileName);
return x;
}
/// <summary>
/// If object exists returns the object else saves a plain object and returns it
/// </summary>
/// <param name="obj">empty placeholder object</param>
/// <returns>Filesystem object</returns>
public async Task<T> GetPersistantObject( T obj,string fileName) {
List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
fileName = _mvxFileStore.NativePath(fileName);
if (!files.Contains(fileName))
{
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson= bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName,objJson);
}
else {
try
{
var temp = await _mvxFileStoreAsync.TryReadTextFileAsync(fileName);
var str = bcEngine.Decrypt(temp.Result, currentkey_temp_dev);
obj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
}
catch(Exception e) {
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);
}
}
return obj;
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public async Task<T> SetPersistantObject(T obj)
{
var fileName = _mvxFileStore.NativePath(typeof(T).ToString().Replace(".", "_"));
var temp = await SetPersistantObject(obj, fileName);
return temp;
}
/// <summary>
/// Saves object to persistant storage with encryption
/// </summary>
/// <param name="obj">object to be stored</param>
/// <returns>Saved object</returns>
public async Task<T> SetPersistantObject(T obj,string fileName)
{
List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
fileName = _mvxFileStore.NativePath(fileName);
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);
return obj;
}
}
java.util.List is not serializable, but java.util.ArrayList is. So just change List to ArrayList on both sites (left before variablename and right for constructor). Also check if your Item implements Serializable

How to serialize a dictionary to a file and deserialize it later in C#? [duplicate]

I have a list of objects and I need to save that somewhere in my computer. I have read some forums and I know that the object has to be Serializable. But it would be nice if I can get an example. For example if I have the following:
[Serializable]
public class SomeClass
{
public string someProperty { get; set; }
}
SomeClass object1 = new SomeClass { someProperty = "someString" };
But how can I store object1 somewhere in my computer and later retrieve?
I just wrote a blog post on saving an object's data to Binary, XML, or Json. You are correct that you must decorate your classes with the [Serializable] attribute, but only if you are using Binary serialization. You may prefer to use XML or Json serialization. Here are the functions to do it in the various formats. See my blog post for more details.
Binary
/// <summary>
/// Writes the given object instance to a binary file.
/// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
/// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the binary file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the binary file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, objectToWrite);
}
}
/// <summary>
/// Reads an object instance from a binary file.
/// </summary>
/// <typeparam name="T">The type of object to read from the binary file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the binary file.</returns>
public static T ReadFromBinaryFile<T>(string filePath)
{
using (Stream stream = File.Open(filePath, FileMode.Open))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return (T)binaryFormatter.Deserialize(stream);
}
}
XML
Requires the System.Xml assembly to be included in your project.
/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(T));
reader = new StreamReader(filePath);
return (T)serializer.Deserialize(reader);
}
finally
{
if (reader != null)
reader.Close();
}
}
Json
You must include a reference to Newtonsoft.Json assembly, which can be obtained from the Json.NET NuGet Package.
/// <summary>
/// Writes the given object instance to a Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite);
writer = new StreamWriter(filePath, append);
writer.Write(contentsToWriteToFile);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the Json file.</returns>
public static T ReadFromJsonFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
reader = new StreamReader(filePath);
var fileContents = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(fileContents);
}
finally
{
if (reader != null)
reader.Close();
}
}
Example
// Write the contents of the variable someClass to a file.
WriteToBinaryFile<SomeClass>("C:\someClass.txt", object1);
// Read the file contents back into a variable.
SomeClass object1= ReadFromBinaryFile<SomeClass>("C:\someClass.txt");
You can use the following:
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
}
}
catch (Exception ex)
{
//Log exception here
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public T DeSerializeObject<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read))
{
objectOut = (T)serializer.Deserialize(reader);
}
}
}
catch (Exception ex)
{
//Log exception here
}
return objectOut;
}
You'll need to serialize to something: that is, pick binary, or xml (for default serializers) or write custom serialization code to serialize to some other text form.
Once you've picked that, your serialization will (normally) call a Stream that is writing to some kind of file.
So, with your code, if I were using XML Serialization:
var path = #"C:\Test\myserializationtest.xml";
using(FileStream fs = new FileStream(path, FileMode.Create))
{
XmlSerializer xSer = new XmlSerializer(typeof(SomeClass));
xSer.Serialize(fs, serializableObject);
}
Then, to deserialize:
using(FileStream fs = new FileStream(path, FileMode.Open)) //double check that...
{
XmlSerializer _xSer = new XmlSerializer(typeof(SomeClass));
var myObject = _xSer.Deserialize(fs);
}
NOTE: This code hasn't been compiled, let alone run- there may be some errors. Also, this assumes completely out-of-the-box serialization/deserialization. If you need custom behavior, you'll need to do additional work.
1. Restore Object From File
From Here you can deserialize an object from file in two way.
Solution-1: Read file into a string and deserialize JSON to a type
string json = File.ReadAllText(#"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Solution-2: Deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}
2. Save Object To File
from here you can serialize an object to file in two way.
Solution-1: Serialize JSON to a string and then write string to a file
string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(#"c:\myObj.json", json);
Solution-2: Serialize JSON directly to a file
using (StreamWriter file = File.CreateText(#"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, myObj);
}
3. Extra
You can download Newtonsoft.Json from NuGet by following command
Install-Package Newtonsoft.Json
You can use JsonConvert from Newtonsoft library.
To serialize an object and write to a file in json format:
File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));
And to deserialize it back into object:
var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));
**1. Convert the json string to base64string and Write or append it to binary file.
2. Read base64string from binary file and deserialize using BsonReader.
**
public static class BinaryJson
{
public static string SerializeToBase64String(this object obj)
{
JsonSerializer jsonSerializer = new JsonSerializer();
MemoryStream objBsonMemoryStream = new MemoryStream();
using (BsonWriter bsonWriterObject = new BsonWriter(objBsonMemoryStream))
{
jsonSerializer.Serialize(bsonWriterObject, obj);
return Convert.ToBase64String(objBsonMemoryStream.ToArray());
}
//return Encoding.ASCII.GetString(objBsonMemoryStream.ToArray());
}
public static T DeserializeToObject<T>(this string base64String)
{
byte[] data = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(data);
using (BsonReader reader = new BsonReader(ms))
{
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize<T>(reader);
}
}
}

How to convert any object to string and string to that object again C# [duplicate]

I have the following method to save an Object to a file:
// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
TextWriter textWriter = new StreamWriter(filename);
xmlSerializer.Serialize(textWriter, toSerialize);
textWriter.Close();
}
I confess I did not write it (I only converted it to a extension method that took a type parameter).
Now I need it to give the xml back to me as a string (rather than save it to a file). I am looking into it, but I have not figured it out yet.
I thought this might be really easy for someone familiar with these objects. If not I will figure it out eventually.
Use a StringWriter instead of a StreamWriter:
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using(StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Note, it is important to use toSerialize.GetType() instead of typeof(T) in XmlSerializer constructor: if you use the first one the code covers all possible subclasses of T (which are valid for the method), while using the latter one will fail when passing a type derived from T. 
 
Here is a link with some example code that motivate this statement, with XmlSerializer throwing an Exception when typeof(T) is used, because you pass an instance of a derived type to a method that calls SerializeObject that is defined in the derived type's base class: http://ideone.com/1Z5J1.
Also, Ideone uses Mono to execute code; the actual Exception you would get using the Microsoft .NET runtime has a different Message than the one shown on Ideone, but it fails just the same.
Serialize and Deserialize XML/JSON (SerializationHelper.cs):
using Newtonsoft.Json;
using System.IO;
using System.Xml.Serialization;
namespace MyProject.Helpers
{
public static class SerializationHelper
{
public static T DeserializeXml<T>(this string toDeserialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringReader textReader = new StringReader(toDeserialize))
{
return (T)xmlSerializer.Deserialize(textReader);
}
}
public static string SerializeXml<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
public static T DeserializeJson<T>(this string toDeserialize)
{
return JsonConvert.DeserializeObject<T>(toDeserialize);
}
public static string SerializeJson<T>(this T toSerialize)
{
return JsonConvert.SerializeObject(toSerialize);
}
}
}
I know this is not really an answer to the question, but based on the number of votes for the question and the accepted answer, I suspect the people are actually using the code to serialize an object to a string.
Using XML serialization adds unnecessary extra text rubbish to the output.
For the following class
public class UserData
{
public int UserId { get; set; }
}
it generates
<?xml version="1.0" encoding="utf-16"?>
<UserData xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserId>0</UserId>
</UserData>
Better solution is to use JSON serialization (one of the best is Json.NET).
To serialize an object:
var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);
To deserialize an object:
var userData = JsonConvert.DeserializeObject<UserData>(userDataString);
The serialized JSON string would look like:
{"UserId":0}
Code Safety Note
Regarding the accepted answer, it is important to use toSerialize.GetType() instead of typeof(T) in XmlSerializer constructor: if you use the first one the code covers all possible scenarios, while using the latter one fails sometimes.
Here is a link with some example code that motivate this statement, with XmlSerializer throwing an Exception when typeof(T) is used, because you pass an instance of a derived type to a method that calls SerializeObject<T>() that is defined in the derived type's base class: http://ideone.com/1Z5J1. Note that Ideone uses Mono to execute code: the actual Exception you would get using the Microsoft .NET runtime has a different Message than the one shown on Ideone, but it fails just the same.
For the sake of completeness I post the full code sample here for future reference, just in case Ideone (where I posted the code) becomes unavailable in the future:
using System;
using System.Xml.Serialization;
using System.IO;
public class Test
{
public static void Main()
{
Sub subInstance = new Sub();
Console.WriteLine(subInstance.TestMethod());
}
public class Super
{
public string TestMethod() {
return this.SerializeObject();
}
}
public class Sub : Super
{
}
}
public static class TestExt {
public static string SerializeObject<T>(this T toSerialize)
{
Console.WriteLine(typeof(T).Name); // PRINTS: "Super", the base/superclass -- Expected output is "Sub" instead
Console.WriteLine(toSerialize.GetType().Name); // PRINTS: "Sub", the derived/subclass
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringWriter textWriter = new StringWriter();
// And now...this will throw and Exception!
// Changing new XmlSerializer(typeof(T)) to new XmlSerializer(subInstance.GetType());
// solves the problem
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
My 2p...
string Serialise<T>(T serialisableObject)
{
var xmlSerializer = new XmlSerializer(serialisableObject.GetType());
using (var ms = new MemoryStream())
{
using (var xw = XmlWriter.Create(ms,
new XmlWriterSettings()
{
Encoding = new UTF8Encoding(false),
Indent = true,
NewLineOnAttributes = true,
}))
{
xmlSerializer.Serialize(xw,serialisableObject);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
public static string SerializeObject<T>(T objectToSerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
MemoryStream memStr = new MemoryStream();
try
{
bf.Serialize(memStr, objectToSerialize);
memStr.Position = 0;
return Convert.ToBase64String(memStr.ToArray());
}
finally
{
memStr.Close();
}
}
public static T DerializeObject<T>(string objectToDerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
byte[] byteArray = Convert.FromBase64String(objectToDerialize);
MemoryStream memStr = new MemoryStream(byteArray);
try
{
return (T)bf.Deserialize(memStr);
}
finally
{
memStr.Close();
}
}
I felt a like I needed to share this manipulated code to the accepted answer - as I have no reputation, I'm unable to comment..
using System;
using System.Xml.Serialization;
using System.IO;
namespace ObjectSerialization
{
public static class ObjectSerialization
{
// THIS: (C): https://stackoverflow.com/questions/2434534/serialize-an-object-to-string
/// <summary>
/// A helper to serialize an object to a string containing XML data of the object.
/// </summary>
/// <typeparam name="T">An object to serialize to a XML data string.</typeparam>
/// <param name="toSerialize">A helper method for any type of object to be serialized to a XML data string.</param>
/// <returns>A string containing XML data of the object.</returns>
public static string SerializeObject<T>(this T toSerialize)
{
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
// using is necessary with classes which implement the IDisposable interface..
using (StringWriter stringWriter = new StringWriter())
{
// serialize a class to a StringWriter class instance..
xmlSerializer.Serialize(stringWriter, toSerialize); // a base class of the StringWriter instance is TextWriter..
return stringWriter.ToString(); // return the value..
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string. If the object has no instance a new object will be constructed if possible.
/// <note type="note">An exception will occur if a null reference is called an no valid constructor of the class is available.</note>
/// </summary>
/// <typeparam name="T">An object to deserialize from a XML data string.</typeparam>
/// <param name="toDeserialize">An object of which XML data to deserialize. If the object is null a a default constructor is called.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static T DeserializeObject<T>(this T toDeserialize, string xmlData)
{
// if a null instance of an object called this try to create a "default" instance for it with typeof(T),
// this will throw an exception no useful constructor is found..
object voidInstance = toDeserialize == null ? Activator.CreateInstance(typeof(T)) : toDeserialize;
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(voidInstance.GetType());
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return (T)xmlSerializer.Deserialize(stringReader);
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string.
/// </summary>
/// <param name="toDeserialize">A type of an object of which XML data to deserialize.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static object DeserializeObject(Type toDeserialize, string xmlData)
{
// create an instance of a XmlSerializer class with the given type toDeserialize..
XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize);
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return xmlSerializer.Deserialize(stringReader);
}
}
}
}
I was unable to use the JSONConvert method suggested by xhafan
In .Net 4.5 even after adding the "System.Web.Extensions" assembly reference I was still unable to access the JSONConvert.
However, once you add the reference you can get the same string print out using:
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonstring = js.Serialize(yourClassObject);
In some rare cases you might want to implement your own String serialization.
But that probably is a bad idea unless you know what you are doing. (e.g. serializing for I/O with a batch file)
Something like that would do the trick (and it would be easy to edit by hand/batch), but be careful that some more checks should be done, like that name doesn't contain a newline.
public string name {get;set;}
public int age {get;set;}
Person(string serializedPerson)
{
string[] tmpArray = serializedPerson.Split('\n');
if(tmpArray.Length>2 && tmpArray[0].Equals("#")){
this.name=tmpArray[1];
this.age=int.TryParse(tmpArray[2]);
}else{
throw new ArgumentException("Not a valid serialization of a person");
}
}
public string SerializeToString()
{
return "#\n" +
name + "\n" +
age;
}
[VB]
Public Function XmlSerializeObject(ByVal obj As Object) As String
Dim xmlStr As String = String.Empty
Dim settings As New XmlWriterSettings()
settings.Indent = False
settings.OmitXmlDeclaration = True
settings.NewLineChars = String.Empty
settings.NewLineHandling = NewLineHandling.None
Using stringWriter As New StringWriter()
Using xmlWriter__1 As XmlWriter = XmlWriter.Create(stringWriter, settings)
Dim serializer As New XmlSerializer(obj.[GetType]())
serializer.Serialize(xmlWriter__1, obj)
xmlStr = stringWriter.ToString()
xmlWriter__1.Close()
End Using
stringWriter.Close()
End Using
Return xmlStr.ToString
End Function
Public Function XmlDeserializeObject(ByVal data As [String], ByVal objType As Type) As Object
Dim xmlSer As New System.Xml.Serialization.XmlSerializer(objType)
Dim reader As TextReader = New StringReader(data)
Dim obj As New Object
obj = DirectCast(xmlSer.Deserialize(reader), Object)
Return obj
End Function
[C#]
public string XmlSerializeObject(object obj)
{
string xmlStr = String.Empty;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = false;
settings.OmitXmlDeclaration = true;
settings.NewLineChars = String.Empty;
settings.NewLineHandling = NewLineHandling.None;
using (StringWriter stringWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
XmlSerializer serializer = new XmlSerializer( obj.GetType());
serializer.Serialize(xmlWriter, obj);
xmlStr = stringWriter.ToString();
xmlWriter.Close();
}
}
return xmlStr.ToString();
}
public object XmlDeserializeObject(string data, Type objType)
{
XmlSerializer xmlSer = new XmlSerializer(objType);
StringReader reader = new StringReader(data);
object obj = new object();
obj = (object)(xmlSer.Deserialize(reader));
return obj;
}

Dynamic Windows form - list with XML

I am creating a dynamic form where if I click on "Add", a new panel appears with a set of buttons.
In this panel, I would like to add a list which will remember how many buttons were created. Thus I thought realize a list, but I want to increment again even though that we restart the console.
May be there is a tip to put it in a XMLfile. In this way my strategy can be renamed with the max of what is present in the CSV, but I do not know how to record and how to increment...
Any idea?
public class SerialStrategyFuture
{
public string StrategyName { get; set; }
public string NumStrategy { get; set; }
}
public void CreateStrategyFuture()
{
ConsoleStrategyItem strategyItemFuture = new ConsoleStrategyItem();
strategyItemFuture.Location = new Point(3, 3);
futureContainer.Height += 85;
futureContainer.Controls.Add(strategyItemFuture);
SerialStrategyFuture strategyFuture = new SerialStrategyFuture();
strategyFuture.StrategyName = "Strat Future ";
strategyFuture.NumStrategy = "How to increment it ???";
XmlSerializer serializer = new XmlSerializer(typeof(SerialStrategyFuture));
TextWriter textWriter = new StreamWriter(#"C:\Users\...");
serializer.Serialize(textWriter,strategyFuture);
textWriter.Close();
ConsoleStrategyItem.Instance.txtStrategyName.Text = "Strat Future 1 ";
}
I am not sure if you can serialize the utureContainer.Controls List. Threfore, I would use this way:
Declare a List ouf your buttons:
List controlList = new List();
each time your users creates a new button:
controlList.add(strategyItemFuture);
Serialize the List when your program closes or another opportune moment:
Deserialize it when your program starts.
build a foreach loop which pulls the buttons from the deserialized List.
Here are the two methods I use to serialize / deserialize
/// <summary>
/// Serializes a file to a compressed XML file. If an error occurs, the exception is NOT caught.
/// </summary>
/// <typeparam name="T">The Type</typeparam>
/// <param name="obj">The object.</param>
/// <param name="fileName">Name of the file.</param>
public static void SerializeToXML<T>(T obj, string fileName)
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
using (GZipStream compressor = new GZipStream(fs, CompressionMode.Compress))
{
serializer.Serialize(compressor, obj);
}
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Deserializes an object from XML.
/// </summary>
/// <typeparam name="T">The object</typeparam>
/// <param name="file">The file.</param>
/// <returns>
/// The deserialized object
/// </returns>
public static T DeserializeFromXml<T>(string file)
{
T result;
XmlSerializer ser = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(file, FileMode.Open))
{
using (GZipStream decompressor = new GZipStream(fs, CompressionMode.Decompress))
{
result = (T)ser.Deserialize(decompressor);
return result;
}
}
}
}
Usage:
SerializeToXML(controlList , yourPath);
this.controlList = DeserializeFromXml<List<ConsoleStrategyItem>>(yourPath);
I am doing a little bit more than just storing the number of buttons, but this has the advantage that you can store more data when your buttons have more logic.

Serialize an object to string

I have the following method to save an Object to a file:
// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
TextWriter textWriter = new StreamWriter(filename);
xmlSerializer.Serialize(textWriter, toSerialize);
textWriter.Close();
}
I confess I did not write it (I only converted it to a extension method that took a type parameter).
Now I need it to give the xml back to me as a string (rather than save it to a file). I am looking into it, but I have not figured it out yet.
I thought this might be really easy for someone familiar with these objects. If not I will figure it out eventually.
Use a StringWriter instead of a StreamWriter:
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using(StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Note, it is important to use toSerialize.GetType() instead of typeof(T) in XmlSerializer constructor: if you use the first one the code covers all possible subclasses of T (which are valid for the method), while using the latter one will fail when passing a type derived from T. 
 
Here is a link with some example code that motivate this statement, with XmlSerializer throwing an Exception when typeof(T) is used, because you pass an instance of a derived type to a method that calls SerializeObject that is defined in the derived type's base class: http://ideone.com/1Z5J1.
Also, Ideone uses Mono to execute code; the actual Exception you would get using the Microsoft .NET runtime has a different Message than the one shown on Ideone, but it fails just the same.
Serialize and Deserialize XML/JSON (SerializationHelper.cs):
using Newtonsoft.Json;
using System.IO;
using System.Xml.Serialization;
namespace MyProject.Helpers
{
public static class SerializationHelper
{
public static T DeserializeXml<T>(this string toDeserialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringReader textReader = new StringReader(toDeserialize))
{
return (T)xmlSerializer.Deserialize(textReader);
}
}
public static string SerializeXml<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
public static T DeserializeJson<T>(this string toDeserialize)
{
return JsonConvert.DeserializeObject<T>(toDeserialize);
}
public static string SerializeJson<T>(this T toSerialize)
{
return JsonConvert.SerializeObject(toSerialize);
}
}
}
I know this is not really an answer to the question, but based on the number of votes for the question and the accepted answer, I suspect the people are actually using the code to serialize an object to a string.
Using XML serialization adds unnecessary extra text rubbish to the output.
For the following class
public class UserData
{
public int UserId { get; set; }
}
it generates
<?xml version="1.0" encoding="utf-16"?>
<UserData xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserId>0</UserId>
</UserData>
Better solution is to use JSON serialization (one of the best is Json.NET).
To serialize an object:
var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);
To deserialize an object:
var userData = JsonConvert.DeserializeObject<UserData>(userDataString);
The serialized JSON string would look like:
{"UserId":0}
Code Safety Note
Regarding the accepted answer, it is important to use toSerialize.GetType() instead of typeof(T) in XmlSerializer constructor: if you use the first one the code covers all possible scenarios, while using the latter one fails sometimes.
Here is a link with some example code that motivate this statement, with XmlSerializer throwing an Exception when typeof(T) is used, because you pass an instance of a derived type to a method that calls SerializeObject<T>() that is defined in the derived type's base class: http://ideone.com/1Z5J1. Note that Ideone uses Mono to execute code: the actual Exception you would get using the Microsoft .NET runtime has a different Message than the one shown on Ideone, but it fails just the same.
For the sake of completeness I post the full code sample here for future reference, just in case Ideone (where I posted the code) becomes unavailable in the future:
using System;
using System.Xml.Serialization;
using System.IO;
public class Test
{
public static void Main()
{
Sub subInstance = new Sub();
Console.WriteLine(subInstance.TestMethod());
}
public class Super
{
public string TestMethod() {
return this.SerializeObject();
}
}
public class Sub : Super
{
}
}
public static class TestExt {
public static string SerializeObject<T>(this T toSerialize)
{
Console.WriteLine(typeof(T).Name); // PRINTS: "Super", the base/superclass -- Expected output is "Sub" instead
Console.WriteLine(toSerialize.GetType().Name); // PRINTS: "Sub", the derived/subclass
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringWriter textWriter = new StringWriter();
// And now...this will throw and Exception!
// Changing new XmlSerializer(typeof(T)) to new XmlSerializer(subInstance.GetType());
// solves the problem
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
My 2p...
string Serialise<T>(T serialisableObject)
{
var xmlSerializer = new XmlSerializer(serialisableObject.GetType());
using (var ms = new MemoryStream())
{
using (var xw = XmlWriter.Create(ms,
new XmlWriterSettings()
{
Encoding = new UTF8Encoding(false),
Indent = true,
NewLineOnAttributes = true,
}))
{
xmlSerializer.Serialize(xw,serialisableObject);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
public static string SerializeObject<T>(T objectToSerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
MemoryStream memStr = new MemoryStream();
try
{
bf.Serialize(memStr, objectToSerialize);
memStr.Position = 0;
return Convert.ToBase64String(memStr.ToArray());
}
finally
{
memStr.Close();
}
}
public static T DerializeObject<T>(string objectToDerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
byte[] byteArray = Convert.FromBase64String(objectToDerialize);
MemoryStream memStr = new MemoryStream(byteArray);
try
{
return (T)bf.Deserialize(memStr);
}
finally
{
memStr.Close();
}
}
I felt a like I needed to share this manipulated code to the accepted answer - as I have no reputation, I'm unable to comment..
using System;
using System.Xml.Serialization;
using System.IO;
namespace ObjectSerialization
{
public static class ObjectSerialization
{
// THIS: (C): https://stackoverflow.com/questions/2434534/serialize-an-object-to-string
/// <summary>
/// A helper to serialize an object to a string containing XML data of the object.
/// </summary>
/// <typeparam name="T">An object to serialize to a XML data string.</typeparam>
/// <param name="toSerialize">A helper method for any type of object to be serialized to a XML data string.</param>
/// <returns>A string containing XML data of the object.</returns>
public static string SerializeObject<T>(this T toSerialize)
{
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
// using is necessary with classes which implement the IDisposable interface..
using (StringWriter stringWriter = new StringWriter())
{
// serialize a class to a StringWriter class instance..
xmlSerializer.Serialize(stringWriter, toSerialize); // a base class of the StringWriter instance is TextWriter..
return stringWriter.ToString(); // return the value..
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string. If the object has no instance a new object will be constructed if possible.
/// <note type="note">An exception will occur if a null reference is called an no valid constructor of the class is available.</note>
/// </summary>
/// <typeparam name="T">An object to deserialize from a XML data string.</typeparam>
/// <param name="toDeserialize">An object of which XML data to deserialize. If the object is null a a default constructor is called.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static T DeserializeObject<T>(this T toDeserialize, string xmlData)
{
// if a null instance of an object called this try to create a "default" instance for it with typeof(T),
// this will throw an exception no useful constructor is found..
object voidInstance = toDeserialize == null ? Activator.CreateInstance(typeof(T)) : toDeserialize;
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(voidInstance.GetType());
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return (T)xmlSerializer.Deserialize(stringReader);
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string.
/// </summary>
/// <param name="toDeserialize">A type of an object of which XML data to deserialize.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static object DeserializeObject(Type toDeserialize, string xmlData)
{
// create an instance of a XmlSerializer class with the given type toDeserialize..
XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize);
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return xmlSerializer.Deserialize(stringReader);
}
}
}
}
I was unable to use the JSONConvert method suggested by xhafan
In .Net 4.5 even after adding the "System.Web.Extensions" assembly reference I was still unable to access the JSONConvert.
However, once you add the reference you can get the same string print out using:
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonstring = js.Serialize(yourClassObject);
In some rare cases you might want to implement your own String serialization.
But that probably is a bad idea unless you know what you are doing. (e.g. serializing for I/O with a batch file)
Something like that would do the trick (and it would be easy to edit by hand/batch), but be careful that some more checks should be done, like that name doesn't contain a newline.
public string name {get;set;}
public int age {get;set;}
Person(string serializedPerson)
{
string[] tmpArray = serializedPerson.Split('\n');
if(tmpArray.Length>2 && tmpArray[0].Equals("#")){
this.name=tmpArray[1];
this.age=int.TryParse(tmpArray[2]);
}else{
throw new ArgumentException("Not a valid serialization of a person");
}
}
public string SerializeToString()
{
return "#\n" +
name + "\n" +
age;
}
[VB]
Public Function XmlSerializeObject(ByVal obj As Object) As String
Dim xmlStr As String = String.Empty
Dim settings As New XmlWriterSettings()
settings.Indent = False
settings.OmitXmlDeclaration = True
settings.NewLineChars = String.Empty
settings.NewLineHandling = NewLineHandling.None
Using stringWriter As New StringWriter()
Using xmlWriter__1 As XmlWriter = XmlWriter.Create(stringWriter, settings)
Dim serializer As New XmlSerializer(obj.[GetType]())
serializer.Serialize(xmlWriter__1, obj)
xmlStr = stringWriter.ToString()
xmlWriter__1.Close()
End Using
stringWriter.Close()
End Using
Return xmlStr.ToString
End Function
Public Function XmlDeserializeObject(ByVal data As [String], ByVal objType As Type) As Object
Dim xmlSer As New System.Xml.Serialization.XmlSerializer(objType)
Dim reader As TextReader = New StringReader(data)
Dim obj As New Object
obj = DirectCast(xmlSer.Deserialize(reader), Object)
Return obj
End Function
[C#]
public string XmlSerializeObject(object obj)
{
string xmlStr = String.Empty;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = false;
settings.OmitXmlDeclaration = true;
settings.NewLineChars = String.Empty;
settings.NewLineHandling = NewLineHandling.None;
using (StringWriter stringWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
XmlSerializer serializer = new XmlSerializer( obj.GetType());
serializer.Serialize(xmlWriter, obj);
xmlStr = stringWriter.ToString();
xmlWriter.Close();
}
}
return xmlStr.ToString();
}
public object XmlDeserializeObject(string data, Type objType)
{
XmlSerializer xmlSer = new XmlSerializer(objType);
StringReader reader = new StringReader(data);
object obj = new object();
obj = (object)(xmlSer.Deserialize(reader));
return obj;
}

Categories

Resources