I've been working at this and have managed to get the json parsed into a C# object. Now the next step was to parse a json array into a List. I have managed to get the job done but I'm pretty sure there is a better way to convert from BsonArray to a List
using (StreamReader file = File.OpenText(filename))
{
try
{
//first up convert to bson
var jsonSampleData = file.ReadToEnd();
//var bsonSampleData = BsonDocument.Parse(jsonSampleData);
//this would be for a single BSOnDocument
var bsonSampleData = BsonSerializer.Deserialize<BsonArray>(jsonSampleData);
var x = bsonSampleData.ToList();
List<ThePlan> lst = new List<ThePlan>();
foreach (var doc in x)
{
var t = BsonSerializer.Deserialize<ThePlan>(doc.AsBsonDocument);
lst.Add(t);
}
}
catch (Exception ex)
{
throw;
}
Edit-Additional Information
To be clear what I am needing to accomplish is taking the given json document and rehydrate it to List. This is further complicated by my being new to mongo and T is a mongo entity representation.
As Andrei pointed out it works fine:
using (StreamReader file = File.OpenText(filename))
{
var jsonSampleData = file.ReadToEnd();
_thePlan = BsonSerializer.Deserialize<List<ThePlan>>(jsonSampleData);
}
Thinking about my struggles yesterday I think it actually had to do with my json where on my early attempts it looked like this:
{
"_id": "57509afbc6b48d3f33b2dfcd",
...
}
In the process of figuring it all out my json matured to:
{
"_id": { "$oid": "57509afbc6b48d3f33b2dfcd" },
.....
}
The troubles I was having with BsonSerializer was likely my bad json and once that was worked out I wasn't astute enough to go back to the BsonSerielizer and try again.
Either go strongly typed all the way or not typed at all.
strongly typed
Assuming these are your types:
public class BaseObject {
[BsonId] public ObjectId id { get; set; }
[BsonElement("plans")] public List<ThePlan> Plans { get; set; }
}
public class ThePlan {
[BsonElement("i")] public int Integer { get; set; }
[BsonElement("s")] public string String { get; set; }
}
and these test utilities:
void ToJsonTyped(BaseObject bo)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
}
string jsonObject = sb.ToString();
BaseObject bo2 = BsonSerializer.Deserialize<BaseObject>(jsonObject);
Assert.AreEqual(bo, bo2);
}
void ToBsonTyped(BaseObject bo)
{
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
bsonObject = ms.ToArray();
}
BaseObject bo1 = BsonSerializer.Deserialize<BaseObject>(bsonObject);
Assert.AreEqual (bo, bo1);
}
you can test:
BaseObject bo = new BaseObject() {
Plans = new List<ThePlan>() {
new ThePlan() {Integer=1, String="one" },
new ThePlan() {Integer=2, String="two" },
new ThePlan() {Integer=3, String="three" } } };
ToBsonTyped(bo);
ToJsonTyped(bo);
not typed at all, combo of BsonDocument and BsonArray
test:
BsonDocument doc = new BsonDocument();
var bsonArray = new BsonArray();
bsonArray.Add(new BsonDocument("one", 1));
bsonArray.Add(new BsonDocument("two", 2));
bsonArray.Add(new BsonDocument("three", 3));
doc.Add( new BsonElement("plans", bsonArray));
ToBsonUnTyped(doc);
ToJsonUnTyped(doc);
test utils:
void ToBsonUnTyped(BsonDocument doc) {
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
bsonObject = ms.ToArray();
}
BsonDocument docActual = BsonSerializer.Deserialize<BsonDocument>(bsonObject);
Assert.AreEqual (doc, docActual);
}
void ToJsonUnTyped(BsonDocument doc)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
}
string jsonObject = sb.ToString();
BsonDocument doc2 = BsonSerializer.Deserialize<BsonDocument>(jsonObject);
Assert.AreEqual(doc, doc2);
}
Related
When a user uses my program, it will generate many thousands of objects over the course of a couple of hours. These cannot accumulate in RAM, so I want to write them to a single file as they are generated. Then, in a different program, the objects must all be deserialized.
When I try to serialize different objects of the same class to the same XML file and then try to deserialize later, I get:
System.InvalidOperationException: 'There is an error in XML document (1, 206).'
Inner Exception
XmlException: There are multiple root elements. Line 1, position 206.
Here is an example of a .NET 6.0 console app that recapitulates this problem:
using System.Xml.Serialization;
using System.IO;
using System.Xml;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
// Serialize a person
using (FileStream stream = new FileStream("people.xml", FileMode.Create))
{
Person jacob = new Person { Name = "Jacob", Age = 33, Alive = true };
XmlSerializer serializer = new XmlSerializer(typeof(Person));
serializer.Serialize(stream, jacob);
}
// Serialize another person to the same file using the "clean XML" method
// https://stackoverflow.com/questions/1772004/how-can-i-make-the-xmlserializer-only-serialize-plain-xml
using (StreamWriter stream = new StreamWriter("people.xml", true))
{
Person rebecca = new Person { Name = "Rebecca", Age = 45, Alive = true };
stream.Write(SerializeToString(rebecca));
}
// Deserialize the people
List<Person> people = new List<Person>();
using (FileStream stream = new FileStream("people.xml", FileMode.Open))
{
XmlSerializer deserializer = new XmlSerializer(typeof(Person));
while (stream.Position < stream.Length)
{
people.Add((Person)deserializer.Deserialize(stream));
}
}
// See the people
foreach (Person person in people)
Console.WriteLine($"Hello. I am {person.Name}. I am {person.Age} and it is {person.Alive} that I am alive.");
}
// Serialize To Clean XML
public static string SerializeToString<T>(T value)
{
var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var serializer = new XmlSerializer(value.GetType());
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, value, emptyNamespaces);
return stream.ToString();
}
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool Alive { get; set; }
public Person()
{
Name = "";
}
}
}
Probably not the perfect answer, but could you de-serialize to a list, append your new person, and then re-serialize?
public static List<Person> ReadPeople(string file)
{
var people = new List<Person>();
if (File.Exists(file))
{
var serializer = new XmlSerializer(typeof(List<Person>));
using (var stream = new FileStream(file, FileMode.Open))
{
people = (List<Person>)serializer.Deserialize(stream);
}
}
return people;
}
public static void SavePerson(string file, Person person)
{
var people = ReadPeople(file);
people.Add(person);
var serializer = new XmlSerializer(typeof(List<Person>));
using (var stream = new FileStream(file, FileMode.Create))
{
serializer.Serialize(stream, people);
}
}
Additionally, on the "FileMode.Create", is the "FileMode.Append" option. The problem with that is it will append lists next to each other, rather than nesting the "people"
NB - I've split this into two functions to give the flexibility of being able to load the file easily
Please I need your help here, I could not write the logic to display the deserialized JSON result on tabPage in Winforms C#
public Form1()
{
var path = #"C:\Users\elitebook\source\repos\ExamCBT\question.json";
string jsonFile = File.ReadAllText(path);
Question q = JsonConvert.DeserializeObject<Question>(jsonFile);
InitializeComponent();
}
jsonFile = tabPage2.ToString();
You can use these methods for serializing & deserializing JSON. Just download the Newtonsoft.Json NuGet package.
static class FileHelper
{
public static void JsonSerialize(object obj, string fileName)
{
using (var sw = new System.IO.StreamWriter($"{fileName}.json"))
using (var jw = new Newtonsoft.Json.JsonTextWriter(sw))
{
var serializer = new Newtonsoft.Json.JsonSerializer();
jw.Formatting = Newtonsoft.Json.Formatting.Indented;
serializer.Serialize(jw, obj);
}
}
public static void JsonDeserialize(out string/*object, List<>, or something else*/ obj, string fileName)
{
using (var sr = new System.IO.StreamReader($"{fileName}.json"))
{
using (var jr = new Newtonsoft.Json.JsonTextReader(sr))
{
var serializer = new Newtonsoft.Json.JsonSerializer();
try
{
obj = serializer.Deserialize<string /*object, List<>, or something else...*/>(jr);
}
catch
{
obj = null;
}
}
}
}
}
And you can add JSON data to TabPage like this.
Label label = new Label(); // label can be textbox, button or something else...
FileHelper.JsonDeserialize(out string /*object, List<>, or something else...*/ data, "test");
label.Text = data //data type is string
tabPage1.Controls.Add(label);
What am I missing here? Is there an option that XMLDiff should care about element names and seek for best match to recognize following changes correctly?
a Helper class for making comparisons between two XML files:
public class XMLDiffer
{
public XDocument Diff(string originalXML, string changedXML)
{
//http://msdn2.microsoft.com/en-us/library/aa302294.aspx
XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreWhitespace);
xmlDiff.Algorithm = XmlDiffAlgorithm.Precise;
StringBuilder diffgramStringBuilder = new StringBuilder();
bool xmlComparisonResult = false;
using (StringReader legacySr = new StringReader(originalXML), nextgenSr = new StringReader(changedXML))
{
using (XmlReader legacyReader = XmlReader.Create(legacySr), nextgenReader = XmlReader.Create(nextgenSr))
{
using (StringWriter sw = new StringWriter(diffgramStringBuilder))
{
using (XmlWriter diffgramWriter = XmlWriter.Create(sw))
{
xmlComparisonResult = xmlDiff.Compare(legacyReader, nextgenReader, diffgramWriter);
}
}
}
}
XDocument xdoc = XDocument.Parse(diffgramStringBuilder.ToString());
return xdoc;
}
public string GetChangeHtml(string originalXML, string changedXML)
{
XmlDiffView view = new XmlDiffView();
var diffgram = Diff(originalXML, changedXML);
string ret = "";
using (StringReader legacySr = new StringReader(originalXML), diffGramSr = new StringReader(diffgram.ToString()))
{
using (XmlReader legacyReader = XmlReader.Create(legacySr), diffgramReader = XmlReader.Create(diffGramSr))
{
using (StringWriter sw = new StringWriter())
{
view.Load(legacyReader, diffgramReader);
view.GetHtml(sw);
ret = sw.ToString();
}
}
}
return ret;
}
}
With Following test:
[TestMethod]
public void XMLDiff_AreNotSame_GetChangeHtmlAll()
{
//Arrange
string source = "<root><child>some text</child><child>more text</child><child1>REMOVED</child1></root>";
//Ordering of the generic child nodes is not changed, but it might
string target = "<root><child>some text CHANGE</child><child>more text</child><child>ADDITION</child></root>";
XMLDiffer differ = new XMLDiffer();
//Act
var diffview = differ.GetChangeHtml(source, target);
//Assert
Assert.IsNotNull(diffview);
}
Produces following (html and table elements added):
https://pste.eu/p/Fm7Z.html
More info about library: http://msdn2.microsoft.com/en-us/library/aa302294.aspx
Nuget link for references: https://www.nuget.org/packages/XMLDiffPatch/
I ended up implementing following classes to get changes:
public class XMLComparer : IEqualityComparer<XNode>
{
public bool Equals(XNode e1, XNode e2)
{
if (!(e1 is XElement)) return true;
if (!(e2 is XElement)) return false;
var el1 = e1 as XElement;
var el2 = e2 as XElement;
return Tuple.Create(el1.Name, el1.Value).Equals(Tuple.Create(el2.Name, el2.Value));
}
public int GetHashCode(XNode n)
{
if (!(n is XElement)) return 0;
var el = n as XElement;
return Tuple.Create(el.Name, el.Value).GetHashCode();
}
}
public class XMLDifference
{
public bool IsNew { get; set; }
public XElement Node { get; set; }
}
public class XMLDifferenceComparer
{
public List<XMLDifference> GetDifferences(string original, string changed)
{
List<XMLDifference> ret = new List<XMLDifference>();
var originalDoc = XDocument.Parse(original);
var changedDoc = XDocument.Parse(changed);
//Get differences that are present in new xml version
var differences = changedDoc.Root.Descendants().Except(originalDoc.Root.Descendants(), new XMLComparer());
ret.AddRange(GetList(differences, true));
//Get differences that have changed since the old xml version
var oldValues = originalDoc.Root.Descendants().Except(changedDoc.Root.Descendants(), new XMLComparer());
ret.AddRange(GetList(oldValues, false));
return ret;
}
private List<XMLDifference> GetList(IEnumerable<XNode> nodes, bool isNew)
{
List<XMLDifference> ret = new List<XMLDifference>();
foreach (XNode d in nodes)
{
var diff = new XMLDifference();
diff.IsNew = isNew;
var el = d as XElement;
diff.Node = el;
ret.Add(diff);
}
return ret;
}
}
This can recognize changes but is not element specific, it cannot map which element exactly was changed and how, caused by lack of unique identifiers for each element.
The main idea for this solution came from here: https://gist.github.com/krcourville/6933451
I'm trying to deserialize a bunch of data that was serialized by an old version of the code. When the data was serialized the classes had a different structure from the current class structure. To keep this data working in my new code, I hade to add the old classes structure to the code just for import this serialized data. I'm calling this classes as 'class'_oldVersions. To deserialize, I'm using this code:
className_oldVersions temp_className = new className_oldVersions();
XmlSerializer testSerializer = new XmlSerializer(typeof(className_oldVersions),
new XmlRootAttribute { ElementName = "className" });
temp_className = (ObservedData_OldVersions)testSerializer.Deserialize(ms_MemoryStream);
This code works fine, and I can deserialize the data using a diffent class name from the original. My problem is when I try to use this same procedure to deserialize an observable collection.
I created a code that reproduce my problem. In this code I serialize an observable collection of class OptimizationVariables and I would like to deserialize to an observable collection of class OptimizationVariablies_NewClass that has similar structure from the original one.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
public class OptimizationVariables
{
public string VariableName { get; set; }
}
public class OptimizationVariables_NewClass
{
public string VariableName { get; set; }
}
public class ModelsCollection
{
private ModelsCollection()
{
}
private ObservableCollection<OptimizationVariables> m_optimizationVariables =
new ObservableCollection<OptimizationVariables>();
public ObservableCollection<OptimizationVariables> OptimizationVariables
{
get { return m_optimizationVariables; }
set { m_optimizationVariables = value; }
}
private ObservableCollection<OptimizationVariables_NewClass> m_optimizationVariables_NewClass =
new ObservableCollection<OptimizationVariables_NewClass>();
public ObservableCollection<OptimizationVariables_NewClass> OptimizationVariables_NewClass
{
get { return m_optimizationVariables_NewClass; }
set { m_optimizationVariables_NewClass = value; }
}
}
class Program
{
static void Main(string[] args)
{
//Here I serialize an ObservableCollection of 2 OptimizationVariables instances
Serialize();
//Here I deserialize for the same class and works fine
Deserialize();
//Here I try to deserialize to a new class with same structure, but different name. I a have an error.
Deserialize2NewClass();
}
static void Serialize()
{
MemoryStream ms;
ObservableCollection<OptimizationVariables> OptimizationVariables2Serialize = new ObservableCollection<OptimizationVariables>();
OptimizationVariables opt_var1 = new OptimizationVariables();
opt_var1.VariableName = "Variable Name 1";
OptimizationVariables2Serialize.Add(opt_var1);
OptimizationVariables opt_var2 = new OptimizationVariables();
opt_var1.VariableName = "Variable Name 2";
OptimizationVariables2Serialize.Add(opt_var1);
ms = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
serializer.Serialize(ms, OptimizationVariables2Serialize);
TextWriter sw = new StreamWriter("XML_File_x64.bin");
sw.WriteLine(Convert.ToBase64String(ms.ToArray()));
sw.Close();
}
static void Deserialize()
{
byte[] memoryData;
MemoryStream ms;
TextReader sw = new StreamReader("XML_File_x64.bin");
memoryData = Convert.FromBase64String(sw.ReadLine());
ms = new MemoryStream(memoryData);
ObservableCollection<OptimizationVariables> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables>();
XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables>)deserializer.Deserialize(ms);
Console.Write(OptimizationVariablesDeserialized.Count());
sw.Close();
}
static void Deserialize2NewClass()
{
byte[] memoryData;
MemoryStream ms;
TextReader sw = new StreamReader("XML_File_x64.bin");
memoryData = Convert.FromBase64String(sw.ReadLine());
ms = new MemoryStream(memoryData);
ObservableCollection<OptimizationVariables_NewClass> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables_NewClass>();
XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables_NewClass>));
OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables_NewClass>)deserializer.Deserialize(ms);
Console.Write(OptimizationVariablesDeserialized.Count());
sw.Close();
}
}
The problem in your code is that the class OptimizationVariables name is saved in the xml data when serializing. but for deserialization it expects a OptimizationVariables_NewClass name which is not within the xml file.
consider the fact that not only the variable names, but also the class names will be used when serializing a class or struct...
So, just changed your code to make it save the data in readable xml file, then replacing "OptimizationVariables" with "OptimizationVariables_NewClass" solved the error:
using System;
using System.Linq;
using System.IO;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
public class OptimizationVariables
{
public string VariableName { get; set; }
}
public class OptimizationVariables_NewClass
{
public string VariableName { get; set; }
}
public class ModelsCollection
{
private ModelsCollection()
{
}
private ObservableCollection<OptimizationVariables> m_optimizationVariables =
new ObservableCollection<OptimizationVariables>();
public ObservableCollection<OptimizationVariables> OptimizationVariables
{
get { return m_optimizationVariables; }
set { m_optimizationVariables = value; }
}
private ObservableCollection<OptimizationVariables_NewClass> m_optimizationVariables_NewClass =
new ObservableCollection<OptimizationVariables_NewClass>();
public ObservableCollection<OptimizationVariables_NewClass> OptimizationVariables_NewClass
{
get { return m_optimizationVariables_NewClass; }
set { m_optimizationVariables_NewClass = value; }
}
}
class Program
{
static void Main(string[] args)
{
Serialize();
Deserialize();
Deserialize2NewClass();
}
static void Serialize()
{
ObservableCollection<OptimizationVariables> OptimizationVariables2Serialize = new ObservableCollection<OptimizationVariables>();
OptimizationVariables opt_var1 = new OptimizationVariables();
opt_var1.VariableName = "Variable Name 1";
OptimizationVariables2Serialize.Add(opt_var1);
OptimizationVariables opt_var2 = new OptimizationVariables();
opt_var1.VariableName = "Variable Name 2";
OptimizationVariables2Serialize.Add(opt_var1);
TextWriter writer = new StreamWriter("XML_File.xml");
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
serializer.Serialize(writer, OptimizationVariables2Serialize);
writer.Close();
}
static void Deserialize()
{
TextReader sw = new StreamReader("XML_File.xml");
ObservableCollection<OptimizationVariables> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables>();
XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables>)deserializer.Deserialize(sw);
Console.Write(OptimizationVariablesDeserialized.Count());
sw.Close();
}
static void Deserialize2NewClass()
{
TextReader sw = new StreamReader("XML_File.xml");
var str = sw.ReadToEnd();
sw.Close();
str = str.Replace("OptimizationVariables", "OptimizationVariables_NewClass");
var stream = new StringReader(str);
ObservableCollection<OptimizationVariables_NewClass> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables_NewClass>();
XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables_NewClass>));
OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables_NewClass>)deserializer.Deserialize(stream);
Console.Write(OptimizationVariablesDeserialized.Count());
}
}
now it works fine!
I can serialize a list really easy:
List<String> fieldsToNotCopy =new List<String> {"Iteration Path","Iteration ID"};
fieldsToNotCopy.SerializeObject("FieldsToNotMove.xml");
Now I need a method like this:
List<String> loadedList = new List<String();
loadedList.DeserializeObject("FieldsToNotMove.xml");
Is there such a method? Or am I going to need to create an XML reader and load it in that way?
EDIT: Turns out there is no built in SerialzeObject. I had made one earlier in my project and forgot about it. When I found it I thought it was built in. In case you are curious this is the SerializeObject that I made:
// 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();
}
There is no such builtin method as SerializeObject but it's not terribly difficult to code one up.
public void SerializeObject(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenWrite(fileName)) {
serializer.Serialize(stream, list);
}
}
And Deserialize
public void Deserialize(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenRead(fileName) ){
var other = (List<string>)(serializer.Deserialize(stream));
list.Clear();
list.AddRange(other);
}
}
These are my serialize/deserialize extension methods that work quite well
public static class SerializationExtensions
{
public static XElement Serialize(this object source)
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType());
var xdoc = new XDocument();
using (var writer = xdoc.CreateWriter())
{
serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") }));
}
return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
}
catch (Exception x)
{
return new XElement("Error", x.ToString());
}
}
public static T Deserialize<T>(this XElement source) where T : class
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(typeof(T));
return (T)serializer.Deserialize(source.CreateReader());
}
catch //(Exception x)
{
return null;
}
}
}
public static class XmlSerializerFactory
{
private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!serializers.ContainsKey(typeOfT))
{
System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
var newSerializer = new XmlSerializer(typeOfT);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
}
You just need to define a type for your list and use it instead
public class StringList : List<String> { }
Oh, and you don't NEED the XmlSerializerFactory, it's just there since creating a serializer is slow, and if you use the same one over and over this speeds up your app.
I'm not sure whether this will help you but I have dome something which I believe to be similar to you.
//A list that holds my data
private List<Location> locationCollection = new List<Location>();
public bool Load()
{
//For debug purposes
Console.WriteLine("Loading Data");
XmlSerializer serializer = new XmlSerializer(typeof(List<Location>));
FileStream fs = new FileStream("CurrencyData.xml", FileMode.Open);
locationCollection = (List<Location>)serializer.Deserialize(fs);
fs.Close();
Console.WriteLine("Data Loaded");
return true;
}
This allows me to deserialise all my data back into a List<> but i'd advise putting it in a try - catch block for safety. In fact just looking at this now is going to make me rewrite this in a "using" block too.
I hope this helps.
EDIT:
Apologies, just noticed you're trying to do it a different way but i'll leave my answer there anyway.
I was getting error while deserializing to object. The error was "There is an error in XML document (0, 0)". I have modified the Deserialize function originally written by #JaredPar to resolve this error. It may be useful to someone:
public static void Deserialize(this List<string> list, string fileName)
{
XmlRootAttribute xmlRoot = new XmlRootAttribute();
xmlRoot.ElementName = "YourRootElementName";
xmlRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(List<string>), xmlRoot);
using (var stream = File.OpenRead(fileName))
{
var other = (List<string>)(serializer.Deserialize(stream));
list.Clear();
list.AddRange(other);
}
}
Create a list of products be serialized
List<string> Products = new List<string>
{
new string("Product 1"),
new string("Product 2"),
new string("Product 3"),
new string("Product 4")
};
Serialization
using (FileStream fs = new FileStream(#"C:\products.txt", FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, Products);
}
Deserialization
using (FileStream fs = new FileStream(#"C:\products.txt", FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
var productList = (List<string>)bf.Deserialize(fs);
}