I have a problem with the xml serialization in c# for windows 7 64 bits.
I want to serialize the following class:
[XmlRoot("configuration")]
public class ClaseQueSeSerializa
{
[XmlElement(ElementName = "Nombre")]
public string Nombre { get; set; }
[XmlElement(ElementName = "Edad")]
public int Edad { get; set; }
[XmlElement(ElementName = "tipoDeFichero", Type = typeof (Enumerados.teOrigenDato))]
//[XmlIgnore]
public Enumerados.teOrigenDato EnumeradoOrigen { get; set; }
public ClaseQueSeSerializa()
{
Nombre = "John Connor";
Edad = 15;
EnumeradoOrigen = Enumerados.teOrigenDato.Fichero;
}
}
And this is the method that serializes:
public static class Serializador
{
public static object Deserializar(string file, Type type)
{
try
{
XmlSerializer xmlSerz = new XmlSerializer(type);
using (StreamReader strReader = new StreamReader(file, Encoding.Default, true))
{
object obj = xmlSerz.Deserialize(strReader);
return obj;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
public static object Serializar(string file, Object obj)
{
try
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
using (StreamWriter stream = new StreamWriter(file, false, Encoding.Default))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(String.Empty, String.Empty);
serializer.Serialize(stream, obj, ns);
}
return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
This is the method call:
if (File.Exists(RUTA_INSTALACION_CAM + #"\prueba.xml"))
claseQueSeSerializa = (ClaseQueSeSerializa)Serializador.Deserializar(RUTA_INSTALACION_CAM + #"\prueba.xml", typeof(ClaseQueSeSerializa));
else
Serializador.Serializar(RUTA_INSTALACION_CAM + #"\prueba.xml", claseQueSeSerializa);
When I run it gives me the following error : error reflecting type NameProject.ErrorSerializarEnumerados
However when I run the generated exe in other pcs, it works.
In addition, the code below serializes my class without errors in my comuter:
[XmlRoot("configuration")]
public class ClaseQueSeSerializa
{
[XmlElement(ElementName = "Nombre")]
public string Nombre { get; set; }
[XmlElement(ElementName = "Edad")]
public int Edad { get; set; }
//[XmlElement(ElementName = "tipoDeFichero", Type = typeof (Enumerados.teOrigenDato))]
[XmlIgnore]
public Enumerados.teOrigenDato EnumeradoOrigen { get; set; }
public ClaseQueSeSerializa()
{
Nombre = "John Connor";
Edad = 15;
EnumeradoOrigen = Enumerados.teOrigenDato.Fichero;
}
}
So I think I have an error when serializing enums only in some windows 7 64 bits
All test PCs have installed windows 7 64bit.
I'm about to go crazy. Some genius knows what's the problem?
I solve my problem updating .net framework 4.0 to 4.5.
Change encoding From : Encoding.Default To: Encoding.UTF8
Related
Hi i need help in converting the XML to Object class so whenever i convert that object back into the XML format i got the same output as expected in some API request.
For now i used online tool(https://json2csharp.com/code-converters/xml-to-csharp) that converts that model into XML but still it's not as expected.
like after convert the root attribute got missed i.e. xmlns:p also the <p: starting tag at name, so calling the API fails because of this as they expected me to send along
Example XML is here:
<p:EIDVBusinessSearch xmlns:p="example.com" xmlns:xsi="abc.com" xsi:schemaLocation="cde.com">
<PermissiblePurpose>
<GLB>{{GLB}}</GLB>
<DPPA>{{DPPA}}</DPPA>
<VOTER>{{VOTER}}</VOTER>
<PermissiblePurpose>
</p:EIDVBusinessSearch>.
I have created a desktop WinForm application using .NET 6 framework and write the following code.
I hope this code will help you in some way to fix your problem.
Note: you have to use XmlAttribute Namespace properly to fix your missing attribute issue.
However, the starting p: will stay remain missing.
EidBusinessSearch class:
[XmlRoot(ElementName = "EIDVBusinessSearch", Namespace = "example.com")]
public class EIDVBusinessSearch
{
[XmlElement(ElementName = "PermissiblePurpose", Namespace = "")]
public PermissiblePurpose? PermissiblePurpose { get; set; }
[XmlAttribute(AttributeName = "p", Namespace = "http://www.w3.org/2000/xmlns/")]
public string? P { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string? Xsi { get; set; }
[XmlAttribute(AttributeName = "schemaLocation", Namespace = "abc.com")]
public string? SchemaLocation { get; set; }
[XmlText]
public string? Text { get; set; }
}
PermissiblePurpose
[XmlRoot(ElementName = "PermissiblePurpose", Namespace = "")]
public class PermissiblePurpose
{
[XmlElement(ElementName = "GLB", Namespace = "")]
public string? GLB { get; set; }
[XmlElement(ElementName = "DPPA", Namespace = "")]
public string? DPPA { get; set; }
[XmlElement(ElementName = "VOTER", Namespace = "")]
public string? VOTER { get; set; }
}
Method to Convert XML to Object:
private void ConvertXMLtoObject()
{
try
{
string xml = "<p:EIDVBusinessSearch xmlns:p=\"example.com\" xmlns:xsi=\"abc.com\" xsi:schemaLocation=\"cde.com\">" +
"\r\n <PermissiblePurpose>" +
"\r\n <GLB>{{GLB}}</GLB>" +
"\r\n <DPPA>{{DPPA}}</DPPA>" +
"\r\n <VOTER>{{VOTER}}</VOTER>" +
"\r\n </PermissiblePurpose>" +
"\r\n</p:EIDVBusinessSearch>";
XmlSerializer serializer = new(typeof(EIDVBusinessSearch));
EIDVBusinessSearch obj = new();
using StringReader reader = new(xml);
obj = (EIDVBusinessSearch)serializer.Deserialize(reader);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
Application.Exit();
}
}
Convert Object to XML:
private void ConvertObjectToXML()
{
try
{
EIDVBusinessSearch obj = new()
{
P = "example.com",
PermissiblePurpose = new()
};
obj.PermissiblePurpose.GLB = "GLB";
obj.PermissiblePurpose.DPPA = "DPPA";
obj.PermissiblePurpose.VOTER = "VOTER";
XmlSerializer serializer = new(obj.GetType());
using StringWriter writer = new();
serializer.Serialize(writer, obj);
string xml = writer.ToString();
label1.Text = xml;
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
Application.Exit();
}
}
Output:
I have the following code:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog.AddExtension = true;
saveFileDialog.DefaultExt = ".xml";
var resultDialog = saveFileDialog.ShowDialog(this);
if (resultDialog == System.Windows.Forms.DialogResult.OK)
{
string fileName = saveFileDialog.FileName;
SerializeObject(ListaDeBotoes, fileName);
}
}
public void SerializeObject(List<MyButton> serializableObjects, string fileName)
{
if (serializableObjects == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObjects.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObjects);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
}
My objective is to save this list of MyButtons, that is my own class (it is a control too if this matter), in a way that i could re-open it on the future. But this way is not working it stops at: XmlSerializer serializer = new XmlSerializer(serializableObjects.GetType()); and the catch exception is called... Any suggestions?
Try this....
Usings.....
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
Functions....
private void Serialize<T>(T data)
{
// Use a file stream here.
using (TextWriter WriteFileStream = new StreamWriter("test.xml"))
{
// Construct a SoapFormatter and use it
// to serialize the data to the stream.
XmlSerializer SerializerObj = new XmlSerializer(typeof(T));
try
{
// Serialize EmployeeList to the file stream
SerializerObj.Serialize(WriteFileStream, data);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Failed to serialize. Reason: {0}", ex.Message));
}
}
}
private T Deserialize<T>() where T : new()
{
//List<Employee> EmployeeList2 = new List<Employee>();
// Create an instance of T
T ReturnListOfT = CreateInstance<T>();
// Create a new file stream for reading the XML file
using (FileStream ReadFileStream = new FileStream("test.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
// Construct a XmlSerializer and use it
// to serialize the data from the stream.
XmlSerializer SerializerObj = new XmlSerializer(typeof(T));
try
{
// Deserialize the hashtable from the file
ReturnListOfT = (T)SerializerObj.Deserialize(ReadFileStream);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Failed to serialize. Reason: {0}", ex.Message));
}
}
// return the Deserialized data.
return ReturnListOfT;
}
// function to create instance of T
public static T CreateInstance<T>() where T : new()
{
return (T)Activator.CreateInstance(typeof(T));
}
Usage....
Serialize(dObj); // dObj is List<YourClass>
List<YourClass> deserializedList = Deserialize<List<YourClass>>();
Your object will be written\read to\from a file called test.xml that you can modify to suit....
Hope that helps....
/////////////////////////////////////////////////////////////////////////
An example class to hold your values for each MyButton object might look something like this......
public partial class PropertiesClass
{
public string colorNow { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.Black.ToArgb()));
public string backgroundColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.Black.ToArgb()));
public string externalLineColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.DarkBlue.ToArgb()));
public string firstColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.Goldenrod.ToArgb()));
public string secondColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.DarkGoldenrod.ToArgb()));
public string mouseEnterColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.PaleGoldenrod.ToArgb()));
public string doubleClickColor { get; set; } = ColorTranslator.ToHtml(Color.FromArgb(Color.Gold.ToArgb()));
public bool shouldIChangeTheColor { get; set; } = true;
public bool selectedToMove { get; set; } = true;
public bool selectedToLink { get; set; } = true;
}
Usage...
List<PropertiesClass> PropertiesClasses = new List<PropertiesClass>();
PropertiesClass PropertiesClass = new PropertiesClass();
PropertiesClasses.Add(PropertiesClass);
Serialize(PropertiesClasses);
If thats not a homework or study stuff you better use Json.NET to serialize your classes. Reinvent the well is probably gonna cost you more time.
I have application, which must contain map. To realize this task I create some classes:
1. Map (contains Image and two objects of Location class)
2. GPSPoint (contains two objects of ICoordinate)
3. ImagePoint (contains two int variables)
4. Location (contains GPSPoint and ImagePoint)
And one interface, and two classes, which realize it:
1. ICoordinate
2. GpsCoordinateDeg
3. GpsCoordinateDegMinSec
All of them implements ISerialization interface and have public void GetObjectData(SerializationInfo, StreamingContext) methods.
I want to save my map in the file, and I realize one of the methods of serialization, but it isn't work - I get void xml file:
<?xml version="1.0"?>
<Map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
I use my class for serialization in this code:
[Serializable]
class Map : ISerializable {
...
public void saveInFile(string filepath) {
Serializer serializer = new Serializer();
serializer.SerializeObject(this, filepath);
}
...
}
This is code of my Serializer:
class Serializer {
public void SerializeObject<T>(T serializableObject, string fileName) {
if (serializableObject == null) { return; }
try {
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream()) {
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
stream.Close();
}
} catch (Exception ex) {
//Log exception here
}
}
public T DeSerializeObject<T>(string fileName) {
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try {
string attributeXml = string.Empty;
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;
}
}
Where is the problem?
As i dont know the complete implementation of your poco classes i suggest you to look further to your GPSPoint class:
GPSPoint (contains two objects of ICoordinate)
You can not serialize an interface. The problem is that an interface is an opaque type. There is no way for the serializer to know what to write out and more importantly what to create when it needs to serialize things back.
You may look into StackOverflow for "serializing interfaces"-postings. I hope it helps.
Bad idea going for generics with serialization since it heavily relies on object boxing and unboxing.
My way of doing this does not rely on implementing ISerializable, rather on the careful use of attributes.
Decorate each class below with [Serializable()], [XmlType(AnonymousType=true)], [XmlRoot(Namespace="", IsNullable=false)]. The enum stands for coordinate types. Derive your existing classes from these ones. Mark properties you do not want serialized with [XmlIgnore] in your derived classes. Make Coordinate below implement your ICoordinate.
public partial class Location {
[XmlElement]
public GPSPoint GPSPoint { get; set; }
[XmlElement]
public ImagePoint ImagePoint { get; set; }
}
public partial class GPSPoint {
[XmlElement(ElementName = "Coordinate", Order = 0)]
public Coordinate Coordinate1 {get; set; }
[XmlElement(Order=1, ElementName="Coordinate")]
public Coordinate Coordinate2 {get;set;}
}
public partial class Coordinate {
[XmlAttribute()]
public ICoordinateType type {get;set;}
}
[Serializable]
public enum ICoordinateType {
/// <remarks/>
GpsCoordinateDegMinSec,
/// <remarks/>
GpsCoordinateDeg,
}
public partial class Map {
[XmlElement(Order=0, IsNullable=true)]
public object Image { get; set; }
/// <remarks/>
[XmlElement(ElementName="Location", Order = 1)]
public Location Location1 {get; set; }
/// <remarks/>
[XmlElement(ElementName = "Location", Order = 2)]
public Location Location2 {get; set; }
}
This is tested and running:
var tc1 = new xyz.Coordinate () {type = xyz.ICoordinateType.GpsCoordinateDeg};
var tc2 = new xyz.Coordinate () {type = xyz.ICoordinateType.GpsCoordinateDegMinSec};
var l1 = new xyz.Location() {
GPSPoint = new xyz.GPSPoint() { Coordinate1 = tc1, Coordinate2 = tc2 },
ImagePoint = new xyz.ImagePoint() { x = 0, y = 0 } };
xyz.Map m = new xyz.Map() {
Image = null,
Location1 = l1,
Location2 = new xyz.Location() {
GPSPoint = new xyz.GPSPoint() {
Coordinate1 = tc1, Coordinate2 = tc2 },
ImagePoint = new xyz.ImagePoint() { x = 1, y = 2 }
} };
XmlSerializer xs = new XmlSerializer(typeof(Map));
using (var fs = File.Create("map.xml") ) { xs.Serialize(fs, m); }
I stomped on some very weird bug which is very hard to reproduce I literally cant reproduce it. We have a window service installed on around 300+ PCs. From time to time config file(xml) that is used by this service become clear (on some of them). Totally clear no xml tags, nothing, 0kb. I have no clue what can cause such problem. No exception is logged in our logs. Even after this config becoming clear it's still running however it's not communicating with our web service. This is the class that is used for xml serialization and deserialization. I can’t find what can be possibly causing such behavior. Of course problem might not be in this particular class. Any suggestions?? Maybe some hints what can cause a file to become clear. When any operation on this file is by using this class.
Sorry for my bad English.
[XmlRootAttribute("xmlconfig", Namespace = "DSD_Config", IsNullable = false)]
public class xmlconfig
{
[XmlElementAttribute(IsNullable = false)]
public string ProgramApteczny { get; set; }
public string Server { get; set; }
public string Database { get; set; }
public string User { get; set; }
public string Password { get; set; }
public string DSDUser { get; set; }
public string DSDPassword { get; set; }
public string DSDServerAdres { get; set; }
//public static string cofFile = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\DSD_Agent\\config.xml";
public static string cofFile = Application.StartupPath + "\\config.xml";
public xmlconfig()
{
}
public xmlconfig(string sProgramApteczny, string sServer, string sDatabase, string sUser, string sPassword, string sDSDUser, string sDSDPassword, string sDSDServerAdres)
{
ProgramApteczny = sProgramApteczny;
Server = sServer;
Database = sDatabase;
User = sUser;
Password = sPassword;
DSDUser = sDSDUser;
DSDPassword = sDSDPassword;
DSDServerAdres = sDSDServerAdres;
}
public static void readXMLConfig(out xmlconfig configFile)
{
XmlSerializer oSerializer = new XmlSerializer(typeof(xmlconfig));
configFile = new xmlconfig();
try
{
using (FileStream fs = new FileStream(cofFile, FileMode.Open, FileAccess.Read))
{
configFile = (xmlconfig)oSerializer.Deserialize(fs);
try
{
configFile.Password = Encryption.DecryptString(configFile.Password);
}
catch (Exception)
{
configFile.Password = configFile.Password;
}
try
{
configFile.DSDPassword = Encryption.DecryptString(configFile.DSDPassword);
}
catch (Exception)
{
configFile.DSDPassword = configFile.DSDPassword;
}
}
}
catch
{
configFile = null;
}
}
public static void writeXMLConfig(string sProgramApteczny, string sServer, string sDatabase, string sUser, string sPassword, string sDSDUser, string sDSDPassword)
{
xmlconfig oxmlconfig = new xmlconfig();
readXMLConfig(out oxmlconfig);
sPassword = Encryption.EncryptString(sPassword);
sDSDPassword = Encryption.EncryptString(sDSDPassword);
if (oxmlconfig == null)
{
oxmlconfig = new xmlconfig(sProgramApteczny, sServer, sDatabase, sUser, sPassword, sDSDUser, sDSDPassword, "");
}
else
{
oxmlconfig.ProgramApteczny = sProgramApteczny;
oxmlconfig.Server = sServer;
oxmlconfig.Database = sDatabase;
oxmlconfig.User = sUser;
oxmlconfig.Password = sPassword;
oxmlconfig.DSDUser = sDSDUser;
oxmlconfig.DSDPassword = sDSDPassword;
}
XmlSerializer oSerializer = new XmlSerializer(typeof(xmlconfig));
TextWriter oStreamWriter = null;
try
{
oStreamWriter = new StreamWriter(cofFile, false);
oSerializer.Serialize(oStreamWriter, oxmlconfig);
}
catch (Exception oException)
{
WriteToLog(DateTime.Now, "Aplikacja wygenerowała następujący wyjątek: " + oException.Message);
// Console.WriteLine("Aplikacja wygenerowała następujący wyjątek: " + oException.Message);
}
finally
{
if (null != oStreamWriter)
{
oStreamWriter.Close();
}
}
}
public static void writeXMLDSDConfig(string sDSDServerAdres)
{
xmlconfig oxmlconfig = new xmlconfig();
readXMLConfig(out oxmlconfig);
if (oxmlconfig == null)
{
throw new Exception("Aplikacja wygenerowała następujący wyjątek: Musisz zdefiniować wszystkie parametry");
}
else
{
oxmlconfig.DSDPassword = Encryption.EncryptString(oxmlconfig.DSDPassword);
oxmlconfig.Password = Encryption.EncryptString(oxmlconfig.Password);
oxmlconfig.DSDServerAdres = sDSDServerAdres;
}
XmlSerializer oSerializer = new XmlSerializer(typeof(xmlconfig));
TextWriter oStreamWriter = null;
try
{
oStreamWriter = new StreamWriter(cofFile, false);
oSerializer.Serialize(oStreamWriter, oxmlconfig);
}
catch (Exception oException)
{
throw new Exception("Aplikacja wygenerowała następujący wyjątek: " + oException.Message);
}
finally
{
if (null != oStreamWriter)
{
oStreamWriter.Close();
}
}
}
}
What I guess, the xml file is accessed by multiple computers/windows services; if so?
Looks no locking mechanism is being used while reading and writing the file. a possible work around would be using a single instance class that only allows one thread to read/write file at one time.
bool isInProgress=false
Public void Read()
{
if(isInProgress==false)
{
isInProgress=true;
try
{
//Do reading or writing
}
finally
{
isInProgress=false;
}
}
}
I have an ArrayList which stores a custom object. I want to serialize that ArrayList to a string so I can save it inside the Application settings.
This question looks to resolve it, but is in java. And I am not smart with XML, so could someone help out?
Serialize an ArrayList of Date object type
I have my ArrayList setup:
...
MyObject tempObj = new MyObject("something",1,"something");
MyCollection.Add(tempObj);
...
And I originally had this. It outputs the string, but the object isn't there:
private string SerializeArrayList(ArrayList obj)
{
System.Xml.XmlDocument doc = new XmlDocument();
Type[] extraTypes = new Type[1];
extraTypes[0] = typeof(MyObject);
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), extraTypes);
System.IO.MemoryStream stream = new System.IO.MemoryStream();
try
{
serializer.Serialize(stream, obj);
stream.Position = 0;
doc.Load(stream);
return doc.InnerXml;
}
catch { throw; }
finally
{
stream.Close();
stream.Dispose();
}
}
EDIT: Code request
public class MyObject
{
private string eN;
private Boolean bE;
private int min;
private Boolean bot;
private string onE;
public MyObject(string na, Boolean b)
{
...
}
public MyObject()
{
}
public string GetSomething()
{
...
I tested your code and it seems to work ok, as long as you have [Serializable] on your object.
Also if you are trying to Serialize the fields, you will have to make them public properties.
My Test:
ArrayList array = new ArrayList();
Rules tempObj = new Rules { onE = "Value", min = 45, eN = "Value" };
array.Add(tempObj);
string result = SerializeArrayList(array);
private string SerializeArrayList(ArrayList obj)
{
XmlDocument doc = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(typeof(ArrayList), new Type[]{typeof(Rules)});
using (MemoryStream stream = new System.IO.MemoryStream())
{
try
{
serializer.Serialize(stream, obj);
stream.Position = 0;
doc.Load(stream);
return doc.InnerXml;
}
catch (Exception ex)
{
}
}
return string.Empty;
}
Object:
[Serializable]
[XmlType(TypeName = "Rules")]
public class Rules
{
// Make fields propertys so they will be serialized
public string eN { get; set; } //Name
public Boolean bE { get; set; } //Whether blocked entirely
public int min { get; set; } //Minutes they are allowed if blocked
public Boolean bot { get; set; } //Create notification if allowance exceed
public string onE { get; set; } //Nothing or CLOSE Process
public Rules(string na, Boolean b)
{
}
public Rules()
{
}
}
I ran into a similar problem, and there is this great program called SharpSerializer, which is available through Nuget. It will handle your ArrayList quite easily, just type the code:
SharpSerializer mySerializer = new SharpSerializer();
mySerializer.Serialize(ArrayList, "filetosaveto.xml");
Here's the link to the website, its free so don't worry about paying anything:
http://www.sharpserializer.com/en/index.html