When I DeSerialize an object from file, the fields whit equal references, don't have same references any more.
This is an example:
in this example, I created an object a1 from type A. then I saved it in a file and load it into new object named a2. In a1 there is b1 and b2 which are same (equal references), so when I set a1.b1.x = 5;, the value of a1.b2.x will change to 5 also, but after save/load, when I set a2.b1.x = 5;, the value of a2.b2.x will not change!!!
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;
namespace test
{
public class SerializeObjectTest
{
public static void Test()
{
var a1 = new A();
a1.init();
SerializeObject<A>(a1, "d:\\1.xml");
var a2 = DeSerializeObject<A>("d:\\1.xml");
a1.b1.x = 5; // this will change also the value of a1.b2.x
a2.b1.x = 5; // this will not!!!!! change also the value of a2.b2.x
MessageBox.Show(
"a1.b1.x==a1.b2.x : " + a1.b1.x + "?=" + a1.b2.x + "\r\n" +
"a2.b1.1==a2.b2.x : " + a2.b1.x + "?=" + a2.b2.x + " !!\r\n", "Save.SaveAble"
);
}
public class A
{
public void init()
{
b1 = new B() { x = 100 };
b2 = b1;
}
public B b1;
public B b2;
}
public class B
{
public double x;
}
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
public static 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);
stream.Close();
}
}
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 static 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);
reader.Close();
}
read.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
return objectOut;
}
}
}
I developed an project my self that can save/load/clone objects in c# and it keeps references to object, it is available here.
It also can save internal and private fields. There are some attributes to how save fields or types (like donsave, saveas, saveif, ...).
Related
I am trying to deserialize an XML file into an object in the Program file of my Windows Forms application as below:
List<UserAccessGroup> AccessGroups = new List<UserAccessGroup>();
AccessGroups = SerializerHelper.DeSerializeObject<List<UserAccessGroup>>(#"C:\Users\Michael"
+ #"\Google Drive\FDM Dev Course Content\Workspace\SystemAdmin\SystemAdmin\"
+ #"XML Data Store\UserAccessGroups.xml");
UserAccessGroup SystemAdmin_App = new UserAccessGroup();
foreach (UserAccessGroup group in AccessGroups)
{
if (group.Name.Equals("Admin Operators"))
{
SystemAdmin_App = group;
}
}
When I run this code, I am getting an unhandled exception in my foreach loop, stating that Access Groups is null.
However, when I copy and paste this snippet of code into a blank console application, it runs fine and when I check AccessGroups with a break point, it has 4 members, as expected.
Can anyone please tell me why deserialization is not working in my program file?
Also, here is my XML file:
<?xml version="1.0"?>
<ArrayOfUserAccessGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserAccessGroup>
<Name>Admin Operators</Name>
<Access_Group>
<int>999</int>
</Access_Group>
</UserAccessGroup>
<UserAccessGroup>
<Name>Shareholders</Name>
<Access_Group />
</UserAccessGroup>
<UserAccessGroup>
<Name>Brokers</Name>
<Access_Group />
</UserAccessGroup>
<UserAccessGroup>
<Name>StockExMgrs</Name>
<Access_Group />
</UserAccessGroup>
</ArrayOfUserAccessGroup>
EDIT: forgot to include the SerializerHelper class that I am using for serialization/deserialization, please see below:
public static class SerializerHelper
{
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(
"SerializerHelper.cs");
public static void SerializeObject<T>(string filepath, T serializableObject)
{
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(filepath);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Serializing: " + ex.Message);
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public static T DeSerializeObject<T>(string filepath)
{
T objectOut = default(T);
if (!System.IO.File.Exists(filepath)) return objectOut;
try
{
string attributeXml = string.Empty;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(filepath);
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);
reader.Close();
}
read.Close();
}
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Deserializing: " + ex.Message);
}
return objectOut;
}
}
EDIT: UserAccessGroup class below:
[Serializable]
public class UserAccessGroup : IUserAccessGroup
{
private String name;
private List<int> AccessGroup = new List<int>();
public String Name
{
get { return name; }
set { name = value; }
}
public List<int> Access_Group
{
get { return AccessGroup; }
set { AccessGroup = value; }
}
public UserAccessGroup()
{
}
public UserAccessGroup(String name)
{
this.name = name;
}
public List<int> getUserIDs()
{
return AccessGroup;
}
public void removeUser(int userID)
{
AccessGroup.Remove(userID);
return;
}
public void addUser(int userID)
{
AccessGroup.Add(userID);
return;
}
}
The main problem can be summarized as:
T objectOut = default(T);
if (!System.IO.File.Exists(filepath)) return objectOut;
try
{
// ...
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Deserializing: " + ex.Message);
}
return objectOut;
(note that default(T) for T=List<UserAccessGroup> is null)
So: for AccessGroups to be null, one of 2 things is happening:
the file does not exist (so the code is exiting near the top)
an exception is being thrown
Check each of these. If the first: add it. If the second: read the .Message, and the .InnerException.Message etc (XmlSerializer is very big on inner-exceptions)
XmlSerializer will not return null for the root object of a list / array, so: it is one of those two things.
Put a breakpoint on the not-exists return, and in the catch, and you should find what is happening. Alternatively, look at where-ever logger writes. Maybe also add something that writes to logger when the file doesn't exist.
I'm basically looking for someone to point me in the right direction on this. I read through some of the Microsoft documentation, but that wasn't very helpful. This is my first attempt at working with XML.
I'm writing an application that needs to store a list of known users and a list of aliases created by each of those users. I've figured out how to have my lists serialized and stored to XML files when the application closes and have it retrieve those when the application opens again, but I don't want to keep the list of users and aliases in memory.
In order for this to work, I need to have the ability to search, edit, and append to the XML file during run time.
The XML structure I envision is something like:
<UserRecord>
<User>Username-1</User>
<AliasRecord>
<Alias>Alias-1</Alias>
<Number>6135551234</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias-2</Alias>
<Number>6131238888</Number>
</AliasRecord>
</UserRecord>
Each user would only have one username but could have multiple aliases. I need to have the ability to add users, add aliases to a new or existing user, and change existing aliases. Usernames would never change, but an entire User record could be deleted.
So far, the only XML I've done in C# uses serialization but I don't think that approach will work for the above.
private void WriteXML()
{
try
{
System.Xml.Serialization.XmlSerializer XMLwriter = new System.Xml.Serialization.XmlSerializer(typeof(MessageRecord));
System.IO.StreamWriter XMLfile = new System.IO.StreamWriter("Saved MessageRecords.xml");
foreach (MessageRecord mr in OutgoingMessages)
{
XMLwriter.Serialize(XMLfile, mr);
}
XMLfile.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Create two classes to represent UserRecord and AliasRecord.
public class UserRecord
{
public string User { get; set; }
public List<AliasRecord> AliasRecords { get; set; }
}
public class AliasRecord
{
public string Alias { get; set; }
public string Number { get; set; }
}
Populate them like this:
var userRecord = new UserRecord
{
User = "UserName1",
AliasRecord = new List<AliasRecord> {
new AliasRecord { Alias = "Alias1", Number = "12345678" },
new AliasRecord { Alias = "Alias2", Number = "23456789" }
}
};
And use this code to serialize/deserialize it:
public static class XmlHelper
{
public static bool NewLineOnAttributes { get; set; }
/// <summary>
/// Serializes an object to an XML string, using the specified namespaces.
/// </summary>
public static string ToXml(object obj, XmlSerializerNamespaces ns)
{
Type T = obj.GetType();
var xs = new XmlSerializer(T);
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
var sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb, ws))
{
xs.Serialize(writer, obj, ns);
}
return sb.ToString();
}
/// <summary>
/// Serializes an object to an XML string.
/// </summary>
public static string ToXml(object obj)
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
return ToXml(obj, ns);
}
/// <summary>
/// Deserializes an object from an XML string.
/// </summary>
public static T FromXml<T>(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
{
return (T)xs.Deserialize(sr);
}
}
/// <summary>
/// Deserializes an object from an XML string, using the specified type name.
/// </summary>
public static object FromXml(string xml, string typeName)
{
Type T = Type.GetType(typeName);
XmlSerializer xs = new XmlSerializer(T);
using (StringReader sr = new StringReader(xml))
{
return xs.Deserialize(sr);
}
}
/// <summary>
/// Serializes an object to an XML file. (Fixed code)
/// </summary>
public static void ToXmlFile(object obj, string filePath)
{
var xs = new XmlSerializer(obj.GetType());
var ns = new XmlSerializerNamespaces();
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
ns.Add("", "");
using (XmlWriter writer = XmlWriter.Create(filePath, ws))
{
xs.Serialize(writer, obj, ns);
}
}
/// <summary>
/// Deserializes an object from an XML file.
/// </summary>
public static T FromXmlFile<T>(string filePath)
{
StreamReader sr = new StreamReader(filePath);
try
{
var result = FromXml<T>(sr.ReadToEnd());
return result;
}
catch (Exception e)
{
throw new Exception("There was an error attempting to read the file " + filePath + "\n\n" + e.InnerException.Message);
}
finally
{
sr.Close();
}
}
}
Example usage:
var result = XmlHelper.ToXml(userRecord);
Result:
<UserRecord>
<User>Username1</User>
<AliasRecords>
<AliasRecord>
<Alias>Alias1</Alias>
<Number>12345678</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias2</Alias>
<Number>23456789</Number>
</AliasRecord>
</AliasRecords>
</UserRecord>
I have problem to call a method in a WCFService. I downladed the file below for a project and I want to call a method in SampleHttpResquestAndResponse class in my WCFService (Also, I tried to do it in a main method and i couldn't succeed it either). However I can't do it, i can't find the method when I type it. How to call those methods in SampleHttpResquestAndResponse class?
using System;
using System.IO;
using System.Net;
using System.Text;
using System.IO.Compression;
using System.Xml.Serialization;
namespace Sample
{
public class SampleHttpResquestAndResponse
{
/// <summary>
/// Adonis servisi ile iletişim kurmayı sağlar.
/// </summary>
/// <typeparam name="T">T</typeparam>
/// <param name="prm_ServiceName">string</param> SearchHotels // BasketHotels // ConfirmHotels
/// <param name="prm_Criteria">object</param>
/// <param name="prm_Url">string</param> "http://xmltest.adonis.com/AdonisServices"
/// <returns>T</returns>
public static T AdonisRequestResponseMethod<T>(string prm_ServiceName, object prm_Criteria, string prm_Url)
{
#region Variables
HttpWebRequest HttpWebRequest;
T ReturnValue;
#endregion
try
{
#region Xml Serializer
var XmlString = SampleHttpResquestAndResponse.ConvertTypeToXml<object>(prm_Criteria).ToString();
#endregion
#region Http Web Request
HttpWebRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}/{1}?prm_CurrentData={2}", prm_Url, prm_ServiceName, XmlString));
HttpWebRequest.ContentType = "text/xml;charset=\"utf-8\"";
HttpWebRequest.Method = "POST";
HttpWebRequest.Timeout = 80000000;
#endregion
#region Http Web Response
StreamWriter StreamWriterPost = new StreamWriter(HttpWebRequest.GetRequestStream());
StreamWriterPost.Write(XmlString);
StreamWriterPost.Close();
HttpWebResponse HttpWebResponse = (HttpWebResponse)HttpWebRequest.GetResponse();
StreamReader StreamReaderResponse = new StreamReader(HttpWebResponse.GetResponseStream(), Encoding.UTF8);
string StringResponse = string.Empty;
if (HttpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
{
using (GZipStream decompress = new GZipStream(HttpWebResponse.GetResponseStream(), CompressionMode.Decompress))
{
StreamReader reader = new StreamReader(decompress);
StringResponse = reader.ReadToEnd();
}
}
else
{
StreamReader reader = new StreamReader(HttpWebResponse.GetResponseStream(), Encoding.UTF8);
StringResponse = reader.ReadToEnd();
}
#endregion
#region Return Value Type Process (DESERIALIZE)
ReturnValue = SampleHttpResquestAndResponse.ConvertXmlToType<T>(StringResponse.ToString()).Data;
#endregion
#region Return Value
return ReturnValue;
#endregion
}
catch (Exception ex)
{
#region Return Value
return ReturnValue = SampleHttpResquestAndResponse.ConvertXmlToType<T>(ex.Message).Data;
#endregion
}
}
public static ResultDTO<T> ConvertXmlToType<T>(string prm_Xml)
{
#region Variables
T ReturnValue;
#endregion
try
{
#region Replace String Value
prm_Xml = prm_Xml.Replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
, "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
prm_Xml = prm_Xml.Replace("<", "<").Replace(">", ">").Replace(""", "\"");
#endregion
#region Deserialize
using (MemoryStream MemoryStream = new MemoryStream())
{
using (StreamWriter StreamWriter = new StreamWriter(MemoryStream))
{
StreamWriter.Write(prm_Xml);
StreamWriter.Flush();
MemoryStream.Position = 0;
XmlSerializer XmlSerializer = new XmlSerializer(typeof(T));
using (StreamReader StreamReader = new StreamReader(MemoryStream))
{
StreamReader.ReadLine();
#region Result Value (SET)
ReturnValue = (T)XmlSerializer.Deserialize(StreamReader);
#endregion
}
}
}
#endregion
#region Return Value
return new ResultDTO<T>
{
Data = ReturnValue,
Success = true
};
#endregion
}
catch (Exception ex)
{
#region Return Value
return new ResultDTO<T>
{
Success = false,
Message = string.Format("Error Type : {0} Code : {1} Method Name : {2} Error Mesage : {3}", "Undetermined", "1000", "ConvertXmlToType", ex.Message),
};
#endregion
}
}
public static string ConvertTypeToXml<T>(T prm_Criteria)
{
#region Variables
XmlSerializer XmlSerializer;
StringWriter StringWriter = new StringWriter();
#endregion
try
{
#region Xml Serializer
XmlSerializer = new XmlSerializer(prm_Criteria.GetType());
XmlSerializer.Serialize(StringWriter, prm_Criteria);
var XmlString = StringWriter.ToString();
#endregion
#region Request Replace
return XmlString = XmlString.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
#endregion
}
catch (Exception ex)
{
throw ex;
}
finally
{
GC.SuppressFinalize(StringWriter);
}
}
}
public class ResultDTO
{
#region Properties
/// <summary>
/// İslem durumu.
/// </summary>
public bool Success { get; set; }
/// <summary>
/// İşlem mesajı.
/// </summary>
public string Message { get; set; }
#endregion
}
public class ResultDTO<T> : ResultDTO
{
#region Fields
/// <summary>
/// Generic data tipi.
/// </summary>
private T data = Activator.CreateInstance<T>();
#endregion
#region Properties
/// <summary>
/// Generic data tipi
/// </summary>
public T Data
{
get
{
if (data == null)
return data = default(T);
return data;
}
set { data = value; }
}
#endregion
}
}
PS: I know it is a little bit silly question, but i couldn't figure it. If it is needed, the below is how i try to call any method in this class in a simple way
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.IO;
using System.Net;
using System.Text;
using System.IO.Compression;
using System.Xml.Serialization;
using Sample;
namespace Adonis
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "AdonisService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select AdonisService.svc or AdonisService.svc.cs at the Solution Explorer and start debugging.
public class AdonisService : IAdonisService
{
ResultDTO res = new ResultDTO();
SampleHttpResquestAndResponse samp = new SampleHttpResquestAndResponse();
public string results()
{
string a1 = "";
object c = new object();
c = 434;
string b = "";
string a = "";
a= samp.AdonisRequestResponseMethod(a, c, b);
}
}
}
AdonisRequestResponseMethod is static, and as such would be called like this:
SampleHttpResquestAndResponse.AdonisRequestResponseMethod(a, b, c);
However, it is also a generic method, so you will have to supply the type you require:
SampleHttpResquestAndResponse.AdonisRequestResponseMethod<string>(a, b, c);
I see 2 things wrong here:
The method is both a generic method.
Since it's a generic method, you must provide a type for it:
SampleHttpResquestAndResponse samp = new SampleHttpResquestAndResponse ();
samp.AdonisRequestResponseMethod<SomeType>(a, b, c);
However, that's not the complete answer,
It's a static method, which means that you can't reference the method from an instance of the class, rather you must reference it from the class type
SampleHttpResquestAndResponse.AdonisRequestResponseMethod<SomeType>(a, b, c);
Oh, and one more thing... SampleHttpResquestAndResponse has an extra 's' in the 'Request' portion of the name. That might give you headaches later. Hope this helps!
I'm basically looking for someone to point me in the right direction on this. I read through some of the Microsoft documentation, but that wasn't very helpful. This is my first attempt at working with XML.
I'm writing an application that needs to store a list of known users and a list of aliases created by each of those users. I've figured out how to have my lists serialized and stored to XML files when the application closes and have it retrieve those when the application opens again, but I don't want to keep the list of users and aliases in memory.
In order for this to work, I need to have the ability to search, edit, and append to the XML file during run time.
The XML structure I envision is something like:
<UserRecord>
<User>Username-1</User>
<AliasRecord>
<Alias>Alias-1</Alias>
<Number>6135551234</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias-2</Alias>
<Number>6131238888</Number>
</AliasRecord>
</UserRecord>
Each user would only have one username but could have multiple aliases. I need to have the ability to add users, add aliases to a new or existing user, and change existing aliases. Usernames would never change, but an entire User record could be deleted.
So far, the only XML I've done in C# uses serialization but I don't think that approach will work for the above.
private void WriteXML()
{
try
{
System.Xml.Serialization.XmlSerializer XMLwriter = new System.Xml.Serialization.XmlSerializer(typeof(MessageRecord));
System.IO.StreamWriter XMLfile = new System.IO.StreamWriter("Saved MessageRecords.xml");
foreach (MessageRecord mr in OutgoingMessages)
{
XMLwriter.Serialize(XMLfile, mr);
}
XMLfile.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Create two classes to represent UserRecord and AliasRecord.
public class UserRecord
{
public string User { get; set; }
public List<AliasRecord> AliasRecords { get; set; }
}
public class AliasRecord
{
public string Alias { get; set; }
public string Number { get; set; }
}
Populate them like this:
var userRecord = new UserRecord
{
User = "UserName1",
AliasRecord = new List<AliasRecord> {
new AliasRecord { Alias = "Alias1", Number = "12345678" },
new AliasRecord { Alias = "Alias2", Number = "23456789" }
}
};
And use this code to serialize/deserialize it:
public static class XmlHelper
{
public static bool NewLineOnAttributes { get; set; }
/// <summary>
/// Serializes an object to an XML string, using the specified namespaces.
/// </summary>
public static string ToXml(object obj, XmlSerializerNamespaces ns)
{
Type T = obj.GetType();
var xs = new XmlSerializer(T);
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
var sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb, ws))
{
xs.Serialize(writer, obj, ns);
}
return sb.ToString();
}
/// <summary>
/// Serializes an object to an XML string.
/// </summary>
public static string ToXml(object obj)
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
return ToXml(obj, ns);
}
/// <summary>
/// Deserializes an object from an XML string.
/// </summary>
public static T FromXml<T>(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
{
return (T)xs.Deserialize(sr);
}
}
/// <summary>
/// Deserializes an object from an XML string, using the specified type name.
/// </summary>
public static object FromXml(string xml, string typeName)
{
Type T = Type.GetType(typeName);
XmlSerializer xs = new XmlSerializer(T);
using (StringReader sr = new StringReader(xml))
{
return xs.Deserialize(sr);
}
}
/// <summary>
/// Serializes an object to an XML file. (Fixed code)
/// </summary>
public static void ToXmlFile(object obj, string filePath)
{
var xs = new XmlSerializer(obj.GetType());
var ns = new XmlSerializerNamespaces();
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
ns.Add("", "");
using (XmlWriter writer = XmlWriter.Create(filePath, ws))
{
xs.Serialize(writer, obj, ns);
}
}
/// <summary>
/// Deserializes an object from an XML file.
/// </summary>
public static T FromXmlFile<T>(string filePath)
{
StreamReader sr = new StreamReader(filePath);
try
{
var result = FromXml<T>(sr.ReadToEnd());
return result;
}
catch (Exception e)
{
throw new Exception("There was an error attempting to read the file " + filePath + "\n\n" + e.InnerException.Message);
}
finally
{
sr.Close();
}
}
}
Example usage:
var result = XmlHelper.ToXml(userRecord);
Result:
<UserRecord>
<User>Username1</User>
<AliasRecords>
<AliasRecord>
<Alias>Alias1</Alias>
<Number>12345678</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias2</Alias>
<Number>23456789</Number>
</AliasRecord>
</AliasRecords>
</UserRecord>
I am using two methods below to serialize/deserialize entity framework object (ver. 4.0).
I tried several ways to accomplish this, and had no luck. Serialization works fine. I get nice xml formatted string, but when I try to deserialize I get error in XML. How is that possible?
Thanks.
public static string SerializeObject(Object obj)
{
XmlSerializer ser = new XmlSerializer(obj.GetType());
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(sb);
ser.Serialize(writer, obj);
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
string xml = doc.InnerXml;
return xml;
}
public static object DeSerializeAnObject(string xml, Type objType)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeReader reader = new XmlNodeReader(doc.DocumentElement);
XmlSerializer ser = new XmlSerializer(objType);
object obj = ser.Deserialize(reader);
return obj;
}
I use generic methods to serialize and deserialize:
/// <summary>
/// Serializes an object to Xml as a string.
/// </summary>
/// <typeparam name="T">Datatype T.</typeparam>
/// <param name="ToSerialize">Object of type T to be serialized.</param>
/// <returns>Xml string of serialized type T object.</returns>
public static string SerializeToXmlString<T>(T ToSerialize)
{
string xmlstream = String.Empty;
using (MemoryStream memstream = new MemoryStream())
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XmlTextWriter xmlWriter = new XmlTextWriter(memstream, Encoding.UTF8);
xmlSerializer.Serialize(xmlWriter, ToSerialize);
xmlstream = UTF8ByteArrayToString(((MemoryStream)xmlWriter.BaseStream).ToArray());
}
return xmlstream;
}
/// <summary>
/// Deserializes Xml string of type T.
/// </summary>
/// <typeparam name="T">Datatype T.</typeparam>
/// <param name="XmlString">Input Xml string from which to read.</param>
/// <returns>Returns rehydrated object of type T.</returns>
public static T DeserializeXmlString<T>(string XmlString)
{
T tempObject = default(T);
using (MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(XmlString)))
{
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
tempObject = (T)xs.Deserialize(memoryStream);
}
return tempObject;
}
// Convert Array to String
public static String UTF8ByteArrayToString(Byte[] ArrBytes)
{ return new UTF8Encoding().GetString(ArrBytes); }
// Convert String to Array
public static Byte[] StringToUTF8ByteArray(String XmlString)
{ return new UTF8Encoding().GetBytes(XmlString); }
i THINK the issue is with this line:
string xml = doc.InnerXml;
you want ALL the xml, not just the xml inside the root node.
Just return sb.ToString(), loading into the XmlDocument is not doing anything.
Some redundancies and usings was excluded. Refactored and cleaned up:
namespace MyProject
{
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public static class Serializer
{
#region Public Methods and Operators
/// <summary>
/// Deserializes Xml string of type T.
/// </summary>
/// <typeparam name="T">Datatype T.</typeparam>
/// <param name="XmlString">Input Xml string from which to read.</param>
/// <returns>Returns rehydrated object of type T.</returns>
public static T DeserializeXmlString<T>(string xmlString)
{
T tempObject;
using (var memoryStream = new MemoryStream(StringToUTF8ByteArray(xmlString)))
{
var xs = new XmlSerializer(typeof(T));
tempObject = (T)xs.Deserialize(memoryStream);
}
return tempObject;
}
/// <summary>
/// Serializes an object to Xml as a string.
/// </summary>
/// <typeparam name="T">Datatype T.</typeparam>
/// <param name="toSerialize">Object of type T to be serialized.</param>
/// <returns>Xml string of serialized type T object.</returns>
public static string SerializeToXmlString<T>(T toSerialize)
{
string xmlstream;
using (var memstream = new MemoryStream())
{
var xmlSerializer = new XmlSerializer(typeof(T));
var xmlWriter = new XmlTextWriter(memstream, Encoding.UTF8);
xmlSerializer.Serialize(xmlWriter, toSerialize);
xmlstream = UTF8ByteArrayToString(((MemoryStream)xmlWriter.BaseStream).ToArray());
}
return xmlstream;
}
#endregion
#region Methods
private static byte[] StringToUTF8ByteArray(string xmlString)
{
return new UTF8Encoding().GetBytes(xmlString);
}
private static string UTF8ByteArrayToString(byte[] arrBytes)
{
return new UTF8Encoding().GetString(arrBytes);
}
#endregion
}
}