Deserialize Dictionary with protobuf-net - c#

Since the BinaryFormatter is giving me trouble serializing a Dictionary on Ios I decided to switch to protobuf-net. And use that to serialize stuff in my Unity3d game. Here is some code:
This is the class that hold all the data:
using System;
using System.Collections.Generic;
using ProtoBuf;
using UnityEngine;
namespace SerializationLib
{
[ProtoContract]
public class GameData
{
[ProtoMember(1)]
public int _coinAmount ;
[ProtoMember(2)]
public int _upgradeLevel;
[ProtoMember(3)]
public Level_Data[] _level_Data;
[ProtoMember(4)]
public CharacterUpgradeList _charUpgradeList;
[ProtoMember(5)]
public SerialVector2 serialVector;
}
[ProtoContract]
public class CharacterUpgradeList
{
private List<UpgradeData>[] upgData;
[ProtoMember(1,OverwriteList = true)]
public Dictionary<string, List<UpgradeData>> upgradeList;
public CharacterUpgradeList()
{
upgData = new List<UpgradeData>[4];
for (int i = 0; i < upgData.Length; i++)
{
upgData[i] = new List<UpgradeData> {
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData()
};
}
upgradeList = new Dictionary<string, List<UpgradeData>>
{
{"Man",upgData[0]},
{"Woman",upgData[1]},
{"Boy",upgData[2]},
{"Girl",upgData[3]}
};
}
}
[ProtoContract]
public class Level_Data
{
[ProtoMember(1)]
public int completion_status;
[ProtoMember(2)]
public int star_Rating;
}
[ProtoContract]
public class UpgradeData
{
[ProtoMember(1)]
public bool lockStatus;
[ProtoMember(2)]
public bool purchased;
}
[ProtoContract]
public struct SerialVector2
{
[ProtoMember(1)]
public float x;
[ProtoMember(2)]
public float y;
public SerialVector2(Vector2 vect)
{
x = vect.x;
y = vect.y;
}
public Vector2 returnVector2()
{
return new Vector2(x, y);
}
}
}
This is the data serializer that I'm using
using System;
using System.Collections.Generic;
using SerializationLib;
using ProtoBuf.Meta;
namespace DataSerializer
{
class Program
{
static void Main(string[] args)
{
var Model = TypeModel.Create();
Model.Add(typeof(GameData), true);
Model.Add(typeof(CharacterUpgradeList), true);
Model.Add(typeof(Level_Data), true);
Model.Add(typeof(UpgradeData), true);
Model.Add(typeof(SerialVector2), true);
Model.AllowParseableTypes = true;
Model.AutoAddMissingTypes = true;
Model.Compile("DataSerializer", "DataSerializer.dll");
}
}
}
this is a protobuf wraper to use in my other c# scripts in unity
using UnityEngine;
using System.IO;
public static class ProtoWraper {
private static DataSerializer m_serialiezer = new DataSerializer();
public static T LoadObjectFromResources<T>(string resourcePath)
{
TextAsset objectAsset = Resources.Load(resourcePath, typeof(TextAsset)) as TextAsset;
if (objectAsset == null)
{
return default(T);
}
T deserializedObject = default(T);
using (MemoryStream m = new MemoryStream(objectAsset.bytes))
{
deserializedObject = (T)m_serialiezer.Deserialize(m, null, typeof(T));
}
return deserializedObject;
}
public static T LoadObjectFromPath<T>(string path)
{
if (!File.Exists(path))
{
return default(T);
}
T deserializedObject = default(T);
using(FileStream f = new FileStream(path,FileMode.Open))
{
deserializedObject = (T)m_serialiezer.Deserialize(f,null,typeof(T));
}
return deserializedObject;
}
public static void SaveObjectToPath<T>(string objectPath, string filename, T serializedObject)
{
if (!Directory.Exists(objectPath))
{
Directory.CreateDirectory(objectPath);
}
using (FileStream f = new FileStream(objectPath + filename, FileMode.OpenOrCreate))
{
m_serialiezer.Serialize(f, serializedObject);
}
}
}
now the problem is when I call data = ProtoWraper.LoadObjectFromPath<GameData>(filename); I get ArgumentException: An element with the same key already exists in the dictionary.

Nevermind, I was being a complete moron and not re-compiling the data serializer after changes to Serializationlib :D. It's all good now.

Related

Protobuf-net: jagged arrays with wrapper

I know that protobuf-net doesn't support a jagged array and a wrapper is a workaround. I've tried to test it, serialization works fine, but deserialization does nothing, i.e. no error, after deserialization the objects are empty.
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Source
{
public Source()
{
List = new List<Dictionary<string, Item>>();
}
[ProtoIgnore]
public List<Dictionary<string, Item>> List { get; set; }
public List<DictionaryWrapper<string, Item>> ListProto
{
get
{
return List.ConvertAll(x => new DictionaryWrapper<string, Item>(x));
}
set
{
List = value.ConvertAll(x => x.Dictionary);
}
}
}
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Item
{
public string Value { get; set; }
}
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public sealed class DictionaryWrapper<TKey, TValue>
{
public DictionaryWrapper()
{
}
public DictionaryWrapper(Dictionary<TKey, TValue> value)
{
Dictionary = value;
}
public Dictionary<TKey, TValue> Dictionary { get; set; }
}
serialization method
public void Test()
{
byte[] data = null;
try
{
var source = new Source();
for (var i = 0; i < 5; i++)
{
source.List.Add(new Dictionary<string, Item> {{i.ToString(), new Item {Value = i.ToString()}}});
}
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, source);
data = stream.ToArray();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Source result;
using (var stream = new MemoryStream(data))
{
result = Serializer.Deserialize<Source>(stream);
}
Console.WriteLine(result.List.Count);
}
UPDATE: I've found a workaround. So this fixes the deserialization, still, don't know why ListProto set was not called.
[ProtoBeforeSerialization]
public void ProtoBeforeSerialization()
{
List1Proto = List1.ConvertAll(x => new DictionaryWrapper<string, Item>(x));
}
[ProtoAfterDeserialization]
public void ProtoAfterDeserialization()
{
List1 = List1Proto.ConvertAll(x => x.Dictionary);
}

csvhelper IsHeaderCaseSensitive Work around

I'm trying to read in a csv file with a Header 'EMAIL', however, I keep getting the CsvMissingFieldException thrown "Fields 'Email' do not exist in the CSV file".
I set up the CSVreader to handle-
csvReader.Configuration.IsHeaderCaseSensitive = false;
but I'm still getting the same issue. Does anyone know a work around? Or why the configuration isn't working?
In my Utilities class:
public static IEnumerable<T> CSVreader<T>(string fileName)
{
using (var fileReader = File.OpenText(fileName))
using (var csvReader = new CsvHelper.CsvReader(fileReader))
{
csvReader.Configuration.IsHeaderCaseSensitive = false;
csvReader.Configuration.RegisterClassMap<OptOutClassMap>();
while (csvReader.Read())
{
var record = csvReader.GetRecord<T>();
yield return record;
}
}
}
In my Class Map Class:
public string Email { get; set; }
public class CustomClassMap : CsvHelper.Configuration.CsvClassMap<CustomMap>
{
public override void CreateMap()
{
Map(m => m.Email);
}
}
It looks like you are not using the correct ClassMap. From your code above, the line:
csvReader.Configuration.RegisterClassMap<OptOutClassMap>();
should be:
csvReader.Configuration.RegisterClassMap<CustomClassMap>();
Your code when modified works as expected.
static void Main(string[] args)
{
var records = CSVreader<Record>("TextFile1.csv");
}
public class Record
{
public string Email { get; set; }
}
public class CustomClassMap : CsvHelper.Configuration.CsvClassMap<Record>
{
public override void CreateMap()
{
Map(m => m.Email);
}
}
public static IEnumerable<T> CSVreader<T>(string fileName)
{
using (var fileReader = File.OpenText(fileName))
using (var csvReader = new CsvHelper.CsvReader(fileReader))
{
csvReader.Configuration.IsHeaderCaseSensitive = false;
csvReader.Configuration.RegisterClassMap<CustomClassMap>();
while (csvReader.Read())
{
var record = csvReader.GetRecord<T>();
yield return record;
}
}
}

DataContractSerializer compatibility after namespace changed

I have a class need to be serialized.
namespace serializedobject
{
[DataContract]
public class Class1
{
string string1_;
string string2_;
EntityA entity_;
[DataMember]
public string string3
{
get { return string1_; }
set { string1_ = value; }
}
[DataMember]
public string string2
{
get { return string2_; }
set { string2_ = value; }
}
[DataMember]
public EntityA Entity
{
get { return entity_; }
set { entity_ = value; }
}
public static Class1 FromXML(string desc)
{
using (MemoryStream ms = new MemoryStream())
{
StreamWriter writer = new StreamWriter(ms);
writer.Write(desc);
writer.Flush();
ms.Seek(0, 0);
DataContractSerializer ser = new DataContractSerializer(typeof(Class1));
return (Class1)ser.ReadObject(ms);
}
}
public string ToXML()
{
using (MemoryStream ms = new MemoryStream())
{
DataContractSerializer ser = new DataContractSerializer(typeof(Class1));
ser.WriteObject(ms, this);
ms.Seek(0, 0);
StreamReader reader = new StreamReader(ms);
return reader.ReadToEnd();
}
}
}
[DataContract]
public class EntityA
{
string name_;
[DataMember]
public string Name
{
get { return name_; }
set { name_ = value; }
}
}
}
it is works fine with FromXML and ToXML. one of serialized context like:
<Class1 xmlns="http://schemas.datacontract.org/2004/07/serializedobject" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Entity><Name>az</Name></Entity><string2 i:nil="true"/><string3>test</string3></Class1>
Later I need to move class EntityA to another namespace "outside", now the serialized context like:
<Class1 xmlns="http://schemas.datacontract.org/2004/07/serializedobject" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Entity xmlns:a="http://schemas.datacontract.org/2004/07/outside"><a:Name>az</a:Name></Entity><string2 i:nil="true"/><string3>test</string3></Class1>
but now the serialized xml which created before change namespace can't be deserialized correctly. I guess this is because of for class "EntityA" changed namespace (xmlns:a added).
does anybody run into the problem before? any suggestion?
You can stop the namespace being added to the XML by specifying [DataContract(Namespace="")]. This relies on you setting that attribute BEFORE you save any xml code.
You can use this approach only if you have not already serialized any data, so this is the approach you would use when first designing a class to be serialized.
(If you have already got serialized data that you must deal with, see the second part of my answer below.)
This code sample has the two classes called Demo in two different namespaces, Test1 and Test2.
We serialize the code using the class from one namespace, and deserialize it using the class from the other namespace:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
namespace ConsoleApp1
{
namespace Test1
{
[DataContract(Namespace="")]
public sealed class Demo
{
[DataMember]
public string Value { get; set; }
}
}
namespace Test2
{
[DataContract(Namespace="")]
public sealed class Demo
{
[DataMember]
public string Value { get; set; }
}
}
sealed class Program
{
private void run()
{
string filename = Path.GetTempFileName();
var demo1 = new Test1.Demo {Value = "DEMO"};
ToFile(filename, demo1);
var demo2 = FromFile<Test2.Demo>(filename);
Console.WriteLine(demo2.Value);
}
public static void ToFile(string filename, object obj)
{
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
using (var streamWriter = File.CreateText(filename))
using (var xmlWriter = XmlWriter.Create(streamWriter, new XmlWriterSettings{Indent = true}))
{
serializer.WriteObject(xmlWriter, obj);
}
}
public static T FromFile<T>(string filename)
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
using (var textReader = File.OpenText(filename))
using (var xmlReader = XmlReader.Create(textReader))
{
return (T)serializer.ReadObject(xmlReader);
}
}
[STAThread]
static void Main(string[] args)
{
new Program().run();
}
}
}
If you have already serialized data without the Namespace="" attribute, then you will need instead to apply the appropriate namespace to the new class:
namespace Test1
{
[DataContract]
public sealed class Demo
{
[DataMember]
public string Value { get; set; }
}
}
namespace Test2
{
// Note the namespace includes both nested namespaces, i.e. ConsoleApp1.Test1
[DataContract(Namespace="http://schemas.datacontract.org/2004/07/ConsoleApp1.Test1")]
public sealed class Demo
{
[DataMember]
public string Value { get; set; }
}
}

Class Serialization To XML

Given the following class design:
public class AllUserCollections
{
public List<UserCollection> UserCollections { get; set; }
public AllUserCollections()
{
this.UserCollections = new List<UserCollection> ();
}
}
public class UserCollection
{
public string UserGroup { get; set; }
public Dictionary<int,User> Users { get; set; }
public UserCollection(string userGroup)
{
this.UserGroup = userGroup;
this.Users = new Dictionary<int, User> ();
}
}
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public AgeGroup UserAgeGroup { get; set; }
}
public enum AgeGroup
{
Twenties,
Thirties,
Fourties,
}
How can I serialize this to XML using my existing serialization class?
public static class HardDriveService
{
private static string docsFolderPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
private const string fileName = "AllUserCollections.xml";
private static string filePath = Path.Combine(docsFolderPath, fileName);
private static bool FileExists(string fullFilePath)
{
if (File.Exists (fullFilePath))
return true;
return false;
}
public static void Save(AllUserCollections allUserCollections)
{
if (FileExists(filePath))
{
File.Delete (filePath);
}
XmlSerializer serializer = new XmlSerializer(allUserCollections.GetType());
using(StreamWriter writer = new StreamWriter(filePath))
{
serializer.Serialize(writer.BaseStream, allUserCollections);
}
}
public static AllUserCollections Read()
{
AllUserCollections allUserCollections = new AllUserCollections();
XmlSerializer serializer = new XmlSerializer(allUserCollections.GetType());
if (FileExists(filePath))
{
StreamReader reader = new StreamReader(filePath);
object deserialized = serializer.Deserialize(reader.BaseStream);
allUserCollections = (AllUserCollections)deserialized;
}
return allUserCollections;
}
}//End of class.
ISSUES
My code seems to fail on this line -
XmlSerializer serializer = new XmlSerializer(allUserCollections.GetType());
I wonder if it's to do with the class needing to be explicitly marked as "serializable"? How would I do this?
Usage
This code will run on an iphone and save/read directly from an app to XML on the iPhone hard drive.
XMLSerializer doesn't support Dictionary out of the box. Your UserCollection class has a Dictionary. See this link for a workaround.
Why doesn't XmlSerializer support Dictionary?
Other than that the XMLSerializer requires that your classes have default constructors (UserCollection and User don't) and each of them must have the [Serializable] attribute.
You could use XElement to build up an XML format. You could use them along the following lines:
public static XElement ToXml(this User user)
{
if (user == null)
{
throw new ArgumentException("User can not be null.");
}
XElement userElement = new XElement("User");
userElement.Add(new XElement("ID", user.ID));
userElement.Add(new XElement("Name", user.Name));
userElement.Add(new XElement("Location", user.Location));
userElement.Add(new XElement("UserAgeGroup", user.UserAgeGroup));
return userElement;
}
public static string ToXml(this UserCollection userCollection)
{
if (userCollection == null)
{
throw new ArgumentException("UserCollection can not be null.");
}
XElement userCollectionElement = new XElement("UserCollection");
userCollectionElement.Add(new XElement("UserGroup", userCollection.UserGroup));
userCollectionElement.Add(new XElement("Users",
userCollection.Users.Select(x => new XElement("User", x.ToXml()));
return userCollectionElement;
}
Calling .ToString() on an XElement should give you an xml-formatted string.
FULL WORKING SOLUTION
Data Model
using System;
using System.Collections.Generic;
namespace iPhoneHardDriveCRUDPrototype
{
[Serializable]
public class AllUserCollections
{
public List<UserCollection> UserCollections { get; set; }
public AllUserCollections()
{
this.UserCollections = new List<UserCollection> ();
}
}
[Serializable]
public class UserCollection
{
public string UserGroup { get; set; }
public SerializableDictionary<int,User> Users { get; set; }
public UserCollection()
{
this.Users = new SerializableDictionary<int, User> ();
}
public UserCollection(string userGroup)
{
this.UserGroup = userGroup;
this.Users = new SerializableDictionary<int, User> ();
}
}
[Serializable]
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public AgeGroup UserAgeGroup { get; set; }
public User()
{
}
}
[Serializable]
public enum AgeGroup
{
Twenties,
Thirties,
Fourties,
}
}
Serializable Dictionary
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace iPhoneHardDriveCRUDPrototype
{
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
}//End of Class....
}
Serializer
using System;
using System.IO;
using System.Xml.Serialization;
using System.Reflection;
using System.Collections.Generic;
namespace iPhoneHardDriveCRUDPrototype
{
public static class HardDriveService
{
private static string docsFolderPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
private const string fileName = "AllUserCollections.xml";
private static string filePath = Path.Combine(docsFolderPath, fileName);
private static bool FileExists(string fullFilePath)
{
if (File.Exists (fullFilePath))
return true;
return false;
}
public static void Save(AllUserCollections allUserCollections)
{
if (FileExists(filePath))
{
File.Delete (filePath);
}
XmlSerializer serializer = new XmlSerializer(allUserCollections.GetType());
using(StreamWriter writer = new StreamWriter(filePath))
{
serializer.Serialize(writer.BaseStream, allUserCollections);
}
}
public static AllUserCollections Read()
{
AllUserCollections allUserCollections = new AllUserCollections();
XmlSerializer serializer = new XmlSerializer(allUserCollections.GetType());
if (FileExists(filePath))
{
StreamReader reader = new StreamReader(filePath);
object deserialized = serializer.Deserialize(reader.BaseStream);
allUserCollections = (AllUserCollections)deserialized;
}
return allUserCollections;
}
}//End of class.
}
Here you have 2 choices XmlSerializer(which will not work with Dictionary or List type deserialization ) or you can use DataContractSerializer which added in .net 3.0 and has a lot advantages here are few: form this post
optimized for speed (about 10% faster than XmlSerializer, typically)
in "opt-in" - only stuff you specifically mark as [DataMember] will be serialized
doesn't support XML attributes (for speed reasons)
Note : you should add reference to the C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Runtime.Serialization.dll
//to serialize
SerializeHelper.Serialize("your filename" ,new AllUserCollections());
// deserialize
var usertCollections = SerializeHelper.Deserialize<AllUserCollections>("yourfile name");
//code
[DataContract]
public class AllUserCollections
{
public List<UserCollection> UserCollections { get; set; }
public AllUserCollections()
{
this.UserCollections = new List<UserCollection>();
}
}
[DataContract()]
public class UserCollection
{
[DataMember]
public string UserGroup { get; set; }
[DataMember]
public Dictionary<int, User> Users { get; set; }
public UserCollection(string userGroup)
{
this.UserGroup = userGroup;
this.Users = new Dictionary<int, User>();
}
}
[DataContract()]
public class User
{ [DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Location { get; set; }
[DataMember]
public AgeGroup UserAgeGroup { get; set; }
}
[DataContract]
public enum AgeGroup
{
Twenties,
Thirties,
Fourties,
}
public static class SerializeHelper
{
public static void Serialize<T>(string fileName, T obj)
{
using (FileStream writer = new FileStream(fileName, FileMode.Create))
{
DataContractSerializer ser =
new DataContractSerializer(typeof(T));
ser.WriteObject(writer, obj);
writer.Close();
}
}
public static T Deserialize<T>(string fileName)
{
T des;
using (FileStream fs = new FileStream(fileName,FileMode.Open))
{
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(T));
des =
(T)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
}
return des;
}
}

Deserialize XML file with objects to Array

This is my code so far:
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Xml;
namespace Opgaver
{
class OpgaveController
{
static ArrayList _arrAktiveOpgaver = new ArrayList();
public ArrayList arrAktiveOpgaver
{
get { return _arrAktiveOpgaver; }
set { _arrAktiveOpgaver = value; }
}
static ArrayList _arrAfsluttedeOpgaver = new ArrayList();
public ArrayList arrAfsluttedeOpgaver
{
get { return _arrAfsluttedeOpgaver; }
set { _arrAfsluttedeOpgaver = value; }
}
static int _opgavenr = 100;
public int opgavenr
{
get { return _opgavenr; }
set { _opgavenr = value; }
}
public void opretOpgave(string opgavenavn, string opgavebeskrivelse, int opgaveprioritet, DateTime opgaveafsluttetdato)
{
DateTime oprettetdato = new DateTime();
oprettetdato = DateTime.Now;
bool opgaveafsluttet = false;
Opgave opgave = new Opgave(oprettetdato, _opgavenr, opgavenavn, opgavebeskrivelse, opgaveprioritet, opgaveafsluttet, opgaveafsluttetdato);
if (opgave.opgaveAfsluttet == false)
{
_arrAktiveOpgaver.Add(opgave);
}
else
{
_arrAfsluttedeOpgaver.Add(opgave);
}
_opgavenr++;
}
public OpgaveController()
{
}
}
public void test()
{
string outfile = #"C:\Folder\Tester.xml";
XmlSerializer xs;
Serialize<List<Opgave>>(arrAktiveOpgaver, outfile);
arrAktiveOpgaver = <List<Opgave>>(outfile);//deserialize data - Generates this error: Error 2 Using the generic type 'System.Collections.Generic.List<T>' requires 1 type arguments P:\Programmerings opgaver\Opgaver\Opgaver\OpgaveController.cs 107 33 Opgaver
}
private void Serialize<T1>(ArrayList arrAktiveOpgaver, string outfile)
{
throw new NotImplementedException();
}
public static T DeserializeFromXml<T>(string inputFile)
{
XmlSerializer s = new XmlSerializer(typeof(T));
T deserializedObject = default(T);
using (TextReader textReader = new StreamReader(inputFile))
{
deserializedObject = (T)s.Deserialize(textReader);
textReader.Close();
}
return deserializedObject;
}
public static void SerializeToXml<T>(T objToSerialize, string outputFile)
{
XmlSerializer s = new XmlSerializer(objToSerialize.GetType());
using (TextWriter textWriter = new StreamWriter(outputFile))
{
s.Serialize(textWriter, objToSerialize);
textWriter.Close();
}
}
}
}
i need to serialize the arraylist, and deserialize it..
and here is my opgave class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Opgaver
{
[Serializable()] public class Opgave : IComparable
{
DateTime _oprettetDato = new DateTime();
public DateTime oprettetDato
{
get { return _oprettetDato; }
set { _oprettetDato = value; }
}
int _opgavenr;
public int opgavenr
{
get { return _opgavenr; }
set { _opgavenr = value; }
}
string _opgaveNavn;
public string opgaveNavn
{
get { return _opgaveNavn; }
set { _opgaveNavn = value; }
}
string _opgaveBeskrivelse;
public string opgaveBeskrivelse
{
get { return _opgaveBeskrivelse; }
set { _opgaveBeskrivelse = value; }
}
int _opgavePrioritet;
public int opgavePrioritet
{
get { return _opgavePrioritet; }
set { _opgavePrioritet = value; }
}
bool _opgaveAfsluttet = false;
public bool opgaveAfsluttet
{
get { return _opgaveAfsluttet; }
set { _opgaveAfsluttet = value; }
}
DateTime _opgaveAfsluttetDato = new DateTime();
public DateTime opgaveAfsluttetDato
{
get { return _opgaveAfsluttetDato; }
set { _opgaveAfsluttetDato = value; }
}
public Opgave()
{
}
public Opgave(DateTime oprettetdato, int opgavenr, string opgavenavn, string opgavebeskrivelse, int opgaveprioritet, bool opgaveafsluttet, DateTime opgaveafsluttetdato)
{
_oprettetDato = oprettetdato;
_opgavenr = opgavenr;
_opgaveNavn = opgavenavn;
_opgaveBeskrivelse = opgavebeskrivelse;
_opgavePrioritet = opgaveprioritet;
_opgaveAfsluttet = opgaveafsluttet;
_opgaveAfsluttetDato = opgaveafsluttetdato;
}
//Sorterings metode
public int CompareTo(object obj)
{
Opgave Compare = (Opgave)obj;
int result = this.opgavenr.CompareTo(Compare.opgavenr);
if (result == 0)
result = this.opgavenr.CompareTo(Compare.opgavenr);
return result;
}
}
}
Use this static methods whenver you want to serialize or deserialize data:
example:
public void test()
{
string outfile = #"C:\Folder\Tester.xml";
SerializeToXml<List<Opgaver>>(arrAktiveOpgaver, outfile);//serialize data
arrAktiveOpgaver = DeserializeFromXml<List<Opgaver>>(outfile);//deserialize data
}
public static T DeserializeFromXml<T>(string inputFile)
{
XmlSerializer s = new XmlSerializer(typeof(T));
T deserializedObject = default(T);
using (TextReader textReader = new StreamReader(inputFile))
{
deserializedObject = (T)s.Deserialize(textReader);
textReader.Close();
}
return deserializedObject;
}
public static void SerializeToXml<T>(T objToSerialize, string outputFile)
{
XmlSerializer s = new XmlSerializer(objToSerialize.GetType());
using (TextWriter textWriter = new StreamWriter(outputFile))
{
s.Serialize(textWriter, objToSerialize);
textWriter.Close();
}
}
Serialize array of Opgave instead of serializing them in loop.
XmlSerializer xs = new XmlSerializer(arrAktiveOpgaver.GetType());
xs.Serialize(sw, arrAktiveOpgaver);
And then deserialize as array of Opgave.

Categories