While developing a test case to understand serialization, I've run into what looks like a straighforward problem but am unable to figure out. I want to be able to add multiple objects to a list<> and then serialize that list (in this case I'm using DataContractJsonSerializer). After creating the objects (node1 and node2), I want to add them to a List<> (cn) and serialize it. However, I get an invalid argument error when adding node1 and node2 ("cannot convert from 'JSON_test.Aspirate' to 'JSON_test.CompositeNode'). I believe it is a matter of letting the array know about the base types, but I don't know how to do that, or if in fact that is the issue (still very new to all this).
Thank you.
namespace JSON_test
{
class Program
{
static void Main(string[] args)
{
Aspirate node1 = new Aspirate(25,40);
Dispense node2 = new Dispense(32,50);
ObjectToSerialize cn = new ObjectToSerialize();
cn.CompositeNode.Add (node1);
cn.CompositeNode.Add (node2);
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize));
ser.WriteObject(stream1, cn.CompositeNode);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
Console.WriteLine(sr.ReadToEnd());
Console.ReadLine();
}
}
[DataContract]
public class ObjectToSerialize
{
private List<CompositeNode> compNode;
[DataMember]
public List<CompositeNode> CompositeNode
{
get {return this.CompositeNode;}
set { this.compNode = value; }
}
public ObjectToSerialize()
{
}
}
[DataContract]
public class CompositeNode
{
}
[DataContract]
public class Aspirate
{
[DataMember]
public string NodeName = "Aspirate";
[DataMember]
public double ZTravelHt;
[DataMember]
public double IndexHt;
public Aspirate(double ZTravelHt, double IndexHt)
{
this.ZTravelHt = ZTravelHt;
this.IndexHt = IndexHt;
}
}
[DataContract]
public class Dispense
{
[DataMember]
public string NodeName = "Dispense";
[DataMember]
public double ZTravelHt;
[DataMember]
public double IndexHt;
public Dispense(double ZTravelHt, double IndexHt)
{
this.ZTravelHt = ZTravelHt;
this.IndexHt = IndexHt;
}
}
}
UPDATE
namespace JSON_test
{
class Program
{
static void Main(string[] args)
{
Aspirate node1 = new Aspirate(25,40);
Dispense node2 = new Dispense(32,50);
ObjectToSerialize cn = new ObjectToSerialize();
cn.CompositeNode.Add (node1);
cn.CompositeNode.Add (node2);
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize),
new Type[] {typeof (Aspirate), typeof (Dispense)});
ser.WriteObject(stream1, cn.CompositeNode);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
Console.WriteLine(sr.ReadToEnd());
Console.ReadLine();
}
}
[DataContract]
[KnownType(typeof(Aspirate))]
[KnownType(typeof(Dispense))]
public class ObjectToSerialize
{
private List<CompositeNode> compNode = new List<CompositeNode>();
[DataMember]
public List<CompositeNode> CompositeNode
{
get {return this.compNode;}
set { this.compNode = value; }
}
public ObjectToSerialize()
{
}
}
[DataContract]
[KnownType(typeof(Aspirate))]
[KnownType(typeof(Dispense))]
public class CompositeNode
{
}
[DataContract]
public class Aspirate : CompositeNode
{
[DataMember]
public string NodeName = "Aspirate";
[DataMember]
public double ZTravelHt;
[DataMember]
public double IndexHt;
public Aspirate(double ZTravelHt, double IndexHt)
{
this.ZTravelHt = ZTravelHt;
this.IndexHt = IndexHt;
}
}
[DataContract]
public class Dispense : CompositeNode
{
[DataMember]
public string NodeName = "Dispense";
[DataMember]
public double ZTravelHt;
[DataMember]
public double IndexHt;
public Dispense(double ZTravelHt, double IndexHt)
{
this.ZTravelHt = ZTravelHt;
this.IndexHt = IndexHt;
}
}
}
You can add a KnownTypeAttribute to the ObjectToSerialize to let the serializer know which types to expect:
[DataContract]
[KnownType(typeof(Aspirate))]
[KnownType(typeof(Dispense))]
public class ObjectToSerialize
{
....
}
I understand that the classes Aspirate and Dispense are derived from CompositeNode? This is not clear from your code example.
You have an error in your code by the way:
get {return this.CompositeNode;}
should be:
get {return this.compNode;}
Update: in resoponse to your question in the comments: you have to intialize the collection inside a constructor of ObjectToSerialize:
public ObjectToSerialize()
{
this.compNode = new List<CompositeNode>();
}
Update 2: The line that is wrong is:
ser.WriteObject(stream1, cn.CompositeNode);
This should be:
ser.WriteObject(stream1, cn);
By the way, you can just write this:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize));
You already defined the known types by using attributes. Adding the known types to the constructor is redundant.
Related
Inheritance from Jobject(Newtonsoft) the existents properties from class not serialized.
Why were the Id and Name properties not serialized?
public class Test : JObject
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
var test = new Test();
test["new_pro"] = 123456;
test.Id = 1;
test.Name = "Dog";
var r = Newtonsoft.Json.JsonConvert.SerializeObject(test);
// Result = { "new_pro":123456}
}
}
Any idea?
Whatever is the reason you want to do that - the reason is simple: JObject implements IDictionary and this case is treated in a special way by Json.NET. If your class implements IDictionary - Json.NET will not look at properties of your class but instead will look for keys and values in the dictionary. So to fix your case you can do this:
public class Test : JObject
{
public int Id
{
get { return (int) this["id"]; }
set { this["id"] = value; }
}
public string Name
{
get { return (string) this["name"]; }
set { this["name"] = value; }
}
}
If you just want to have both dynamic and static properties on your object - there is no need to inherit from JObject. Instead, use JsonExtensionData attribute:
public class Test {
public int Id { get; set; }
public string Name { get; set; }
[JsonExtensionData]
public Dictionary<string, JToken> AdditionalProperties { get; set; } = new Dictionary<string, JToken>();
}
var test = new Test();
test.AdditionalProperties["new_pro"] = 123456;
test.Id = 1;
test.Name = "Dog";
var r = Newtonsoft.Json.JsonConvert.SerializeObject(test);
I'm trying to find out a solution for this, but I'm not sure if it's possible or not.
I have a base class, lets say
public class A
{
[XmlAttribute("Date")]
public DateTime Date {get;set;}
}
and a derived class:
public class B: A
{
[XmlAttribute("Date")]
public new String StringDate {get;set;}
}
I have to serialize a Xml.
The value of "Date" on the Xml, is String and in fact it's not a DateTime format string. But I use "A" for many other stuff so I cannot just change it to String without affecting other parts of the program. Sadly it is not an option.
So my idea is to create a derived class "B" who inherit everything of "A" and overrided the property Date to get it fill from the deserialization and then format it to DateTime.
I read about virtual or abstracts but I'm not acquainted with it and don't have any clue about it, if it is the solution maybe someone can guide me on the first steps.
Anyone can help me?
EDIT
XML:
<Vorgang Vorgang="HQHT8GTQ">
<Vertragsbeginn Vertragsbeginn="20140202" />
</Vorgang>
Class A:
[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
[IgnoreDataMember]
public DateTime Vertragsbeginn { get; set; }
}
Class B:
public class VorgangOverride : UTILMD.Vorgang
{
private string datestring;
[XmlAttribute("Vertragsbeginn")]
public new String Vertragsbeginn {
get { return datestring; }
set
{
base.Vertragsbeginn = DateUtil.StringToDate(value, EDIEnums.Vertragsbeginn);
datestring = value;
}
}
}
Deserialization method:
private static VorgangOverride Deserialize (XmlNode inVorgang)
{
using (MemoryStream stm = new MemoryStream())
{
using (StreamWriter stw = new StreamWriter(stm))
{
stw.Write(inVorgang.OuterXml);
stw.Flush();
stm.Position = 0;
XmlRootAttribute xRoot = new XmlRootAttribute { ElementName = "Vorgang", IsNullable = true };
var serializer = new XmlSerializer(typeof(VorgangOverride), xRoot);
VorgangOverride podItem = (VorgangOverride) serializer.Deserialize(stm);
return podItem;
}
}
}
EDIT:
Solved using
[XmlRoot("Vorgang")]
public class VorgangOverride
{
public VorgangOverride()
{
}
#region Public Properties
public string datestring;
[XmlElement("Vertragsbeginn")]
public Vertragsbeginn VertragsbeginnAsString { get ; set ;}
#endregion
}
public class Vertragsbeginn
{
[XmlAttribute("Vertragsbeginn")]
public String vertragsbeginn { get; set; }
}
I found the solution:
[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
[XmlIgnore] // use XmlIgnore instead IgnoreDataMember
public DateTime Vertragsbeginn { get; set; }
}
// this class map all elements from the xml that you show
[XmlRoot("Vorgang")] // to map the Xml Vorgang as a VorgangOverride instance
public class VorgangOverride : Vorgang
{
[XmlAttribute("Vorgang2")] // to map the Vorgang attribute
public string VorgangAttribute { get; set; }
[XmlElement(ElementName = "Vertragsbeginn")] // to map the Vertragsbeginn element
public Vertragsbeginn VertragsbeginnElement
{
get { return _vertragsbeginn; }
set
{
base.Vertragsbeginn = new DateTime(); // here I Assing the correct value to the DateTime property on Vorgan class.
_vertragsbeginn = value;
}
}
private Vertragsbeginn _vertragsbeginn;
}
// this class is used to map the Vertragsbeginn element
public class Vertragsbeginn
{
[XmlAttribute("Vertragsbeginn")] // to map the Vertragsbeginn attriubute on the Vertragsbeginn element
public string VertragsbeginnAttribute { get; set; }
}
later I say:
var string xmlContent =
#"<Vorgang Vorgang2=""HQHT8GTQ"">
<Vertragsbeginn Vertragsbeginn=""20140202"" />
</Vorgang>";
var a = Deserialize<VorgangOverride>(xmlContent);
and this is the method to Deserialize:
// method used to deserialize an xml to object
public static T Deserialize<T>(string xmlContent)
{
T result;
var xmlSerializer = new XmlSerializer(typeof(T));
using (TextReader textReader = new StringReader(xmlContent))
{
result = ((T)xmlSerializer.Deserialize(textReader));
}
return result;
}
You will not be able to override a property with an other class type.
The reason is Polymorphism. (more information: https://msdn.microsoft.com/en-us/library/ms173152.aspx)
You can cast the class B to class A. Which means the class B must have all the properties and methods class A has, too. But in your case class B would have a String rather than a Date called Date. Which is simply not possible.
I have an issue with the .NET XML Serializer where I have do different XML Elements with different names that map to the same type. Basically, the objects should be exactly the same, but I want them to have a string or enum or something that identifies which of the three possible element names were used. So here's an example:
<Body>
<MyTypeA>
<Foo>bar</Foo>
</MyTypeA>
<MyTypeB>
<Foo>bar</Foo>
</MyTypeB>
</Body>
Now, for the classes, MyTypeA and MyTypeB will both be the same type. For example:
public class Body {
public MyType MyTypeA { get; set; }
public MyType MyTypeB { get; set; }
}
public class MyType {
public string Foo { get; set; }
[XmlIgnore]
public MyTypeType { get; set; }
}
public enum MyTypeType
{
MyTypeA,
MyTypeB
}
When serializing it works fine, because I can always just ensure one way or another that the enum is set properly before serializing. But when deserializing it is not getting set and I'm not sure there's a way how.
For the record, I unfortunately don't get to set the schema, otherwise I would have built it in such a way that I didn't have this problem.
If i understood your question correctly, this might help you. Just write you XML file path on the 4th line and try it.
namespace ConsoleApplication1
{
class Program
{
//private const string xmlPath = #"C:\Users\Jumast\Desktop\StackOverflowQuestion.xml";
private const string xmlPath, // put the file path here
static Body makeBody()
{
var instance1 = new MyType() { Category = Category.MyTypeA, Foo = "bar" };
var instance2 = new MyType() { Category = Category.MyTypeB, Foo = "bar" };
return new Body(){Instance1 = instance1, Instance2 = instance2};
}
static void serializeBody(Body body, string path)
{
var ser = new DataContractSerializer(body.GetType(), body.GetType().Name, "");
using (var w = XmlWriter.Create(path, new XmlWriterSettings() { Indent = true }))
{
ser.WriteObject(w, body);
}
}
static Body deseerializeBody(string xmlPath)
{
Body deserializedBody;
var ser = new XmlSerializer(typeof(Body));
using (Stream stream = File.OpenRead(xmlPath))
{
deserializedBody = (Body)ser.Deserialize(stream);
}
return deserializedBody;
}
static void writeBodyToConsole(Body body)
{
Console.WriteLine("Instance1: " + body.Instance1);
Console.WriteLine("Instance2: " + body.Instance2);
Console.ReadKey();
}
static void Main(string[] args)
{
serializeBody(makeBody(), xmlPath);
writeBodyToConsole(deseerializeBody(xmlPath));
}
}
public class Body : IXmlSerializable
{
#region Properties
public MyType Instance1 { get; set; }
public MyType Instance2 { get; set; }
#endregion
#region IXmlSerializable
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement();
Instance1 = new MyType(reader);
Instance2 = new MyType(reader);
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
Instance1.WriteXml(writer);
Instance2.WriteXml(writer);
}
#endregion
}
public class MyType : IXmlSerializable
{
#region Fields
private Category _category;
#endregion
#region Constructors
public MyType()
{
_category = Category.nil;
Foo = string.Empty;
}
public MyType(XmlReader reader) { ReadXml(reader);}
#endregion
#region Methods
public override string ToString()
{
var sb = new StringBuilder();
sb.Append(string.Format("Foo = {0}", Foo));
sb.Append(" , ");
sb.Append(string.Format("Category = {0}", Category));
return sb.ToString();
}
#endregion
#region Properties
public string Foo { get; set; }
public Category Category
{
get { return this._category; }
set { this._category = value; }
}
#endregion
#region IXmlSerializable
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
Enum.TryParse(reader.Name, out _category);
reader.Read();
Foo = reader.ReadElementContentAsString("Foo", "");
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement(this.Category.ToString(), "");
writer.WriteElementString("Foo", Foo);
writer.WriteEndElement();
}
#endregion
}
public enum Category
{
MyTypeA,
MyTypeB,
nil
}
}
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;
}
}
Trying to deserialize an instance of this class
[Serializable]
public class InstalledMeter : ISerializable
{
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Description", Description);
info.AddValue("Latitude", Latitude);
info.AddValue("Longitude", Longitude);
}
}
The instance:
new InstalledMeter {Description = "Something", Latitude = 0.0, Longitude = 0.0};
My Serialization methods
public static class SerializeString
{
public static string SerializeObject<T>(this T toSerialize)
{
var xmlSerializer = new XmlSerializer(toSerialize.GetType());
var textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
public static T XmlDeserializeFromString<T>(this string objectData)
{
return (T)XmlDeserializeFromString(objectData, typeof(T));
}
public static object XmlDeserializeFromString(string objectData, Type type)
{
var serializer = new XmlSerializer(type);
object result;
using (TextReader reader = new StringReader(objectData))
{
result = serializer.Deserialize(reader);
}
return result;
}
}
But when I serialize the object it has these values
(guessing an answer based on your previous question - Error passing parameters to mvvmcross viewmodels)
If you are doing this in MvvmCross, then I would avoid this xml problem altogether and just use JSON serialization
var jsonText = JSONConvert.SerializeObject(installedMeter);
and
var installedMeter = JSONConvert.DeserializeObject<InstalledMeter>(jsonText);
using just:
public class InstalledMeter
{
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}