Need help in converting the XML to Objects - c#

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:

Related

I couldn't create subnodes with different prefix in same parent node

I'm trying to create a XML something like this :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
- <inventory_report:inventoryReportMessage xmlns:inventory_report="urn:gs1:ecom:inventory_report:xsd:3" xmlns:sh="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" xmlns:ecom_common="urn:gs1:ecom:ecom_common:xsd:3" xmlns:shared_common="urn:gs1:shared:shared_common:xsd:3">
- <sh:StandardBusinessDocumentHeader>
<sh:HeaderVersion>Standard Business Header version 1.3</sh:HeaderVersion>
- <sh:Sender>
<sh:Identifier Authority="GS1">0000</sh:Identifier>
- <sh:ContactInformation>
<sh:Contact>some one</sh:Contact>
<sh:EmailAddress>someone#example.com</sh:EmailAddress>
<sh:TelephoneNumber>00357</sh:TelephoneNumber>
<sh:ContactTypeIdentifier>IT Support</sh:ContactTypeIdentifier>
</sh:ContactInformation>
</sh:Sender>
I'm using the below code for creating the XML -->
var xelementNode = doc.CreateElement("inventory_report", "inventoryReportMessage","urn:gs1:ecom:inventory_report:xsd:3");
doc.AppendChild(xelementNode);
var xelementSubNode = doc.CreateElement("sh", xelementNode, "StandardBusinessDocumentHeades","");
xelementNode.AppendChild(xelementSubNode);
I'm getting this output for the above code -->
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
- <inventory_report:inventoryReportMessage xmlns:inventory_report="urn:gs1:ecom:inventory_report:xsd:3">
- <StandartBusinessDocumentHeader>
<HeaderVersion>Standard Business Header Version 1.3</HeaderVersion>
- <Sender>
<Identifier>GS1</Identifier>
- <ContactInformation>
<Contact>Turkey IT Support</Contact>
<EmailAddress>someone#example.com</EmailAddress>
<TelephoneNumber>00 13</TelephoneNumber>
<ContactTypeIdentifier>IT Support</ContactTypeIdentifier>
</ContactInformation>
</Sender>
</StandartBusinessDocumentHeader>
</inventory_report:inventoryReportMessage>
The second prefix ("sh") doesn't work. Can someone help me???
For serialization approach, you can define classes:
public class ContactInformation
{
[XmlElement(ElementName = "Contact")]
public string Contact { get; set; }
[XmlElement(ElementName = "EmailAddress")]
public string EmailAddress { get; set; }
[XmlElement(ElementName = "TelephoneNumber")]
public string TelephoneNumber { get; set; }
[XmlElement(ElementName = "ContactTypeIdentifier")]
public string ContactTypeIdentifier { get; set; }
}
public class Identifier
{
[XmlAttribute("Authority")]
public string Authority { get; set; }
[XmlText]
public string Value { get; set; }
}
public class Sender
{
[XmlElement(ElementName = "Identifier")]
public Identifier Identifier { get; set; }
[XmlElement(ElementName = "ContactInformation")]
public ContactInformation ContactInformation { get; set; }
}
public class StandartBusinessDocumentHeader
{
[XmlElement(ElementName = "HeaderVersion")]
public string HeaderVersion { get; set; }
[XmlElement(ElementName = "Sender")]
public Sender Sender { get; set; }
}
[XmlRoot(ElementName = "inventoryReportMessage", Namespace = "urn:gs1:ecom:inventory_report:xsd:3")]
public class InventoryReportMessage
{
[XmlElement("StandardBusinessDocumentHeader", Namespace = "http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader")]
public StandartBusinessDocumentHeader Header { get; set; }
}
then serialize those as below:
var report = new InventoryReportMessage
{
Header = new StandartBusinessDocumentHeader {
HeaderVersion = "Standard Business Header version 1.3",
Sender = new Sender
{
Identifier = new Identifier
{
Authority = "GS1",
Value = "0000"
},
ContactInformation = new ContactInformation
{
Contact = "some one",
EmailAddress = "someone#example.com",
TelephoneNumber = "00357",
ContactTypeIdentifier = "IT Support"
}
}
}
};
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
var settings = new XmlWriterSettings {
Indent = true
};
using (var xmlWriter = XmlWriter.Create(writer, settings))
{
xmlWriter.WriteStartDocument(false);
var serializer = new XmlSerializer(typeof(InventoryReportMessage));
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("inventory_report", "urn:gs1:ecom:inventory_report:xsd:3");
namespaces.Add("sh", "http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader");
namespaces.Add("ecom_common", "urn:gs1:ecom:ecom_common:xsd:3");
namespaces.Add("shared_common", "urn:gs1:shared:shared_common:xsd:3");
serializer.Serialize(xmlWriter, report, namespaces);
}
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
Console.ReadLine();
Using xml linq. I like to create a string header and then add dynamic values in code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string header =
"<inventory_report:inventoryReportMessage xmlns:inventory_report=\"urn:gs1:ecom:inventory_report:xsd:3\" xmlns:sh=\"http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader\" xmlns:ecom_common=\"urn:gs1:ecom:ecom_common:xsd:3\" xmlns:shared_common=\"urn:gs1:shared:shared_common:xsd:3\">" +
"<sh:StandardBusinessDocumentHeader>" +
"<sh:HeaderVersion>Standard Business Header version 1.3</sh:HeaderVersion>" +
"<sh:Sender>" +
"</sh:Sender>" +
"</sh:StandardBusinessDocumentHeader>" +
"</inventory_report:inventoryReportMessage>";
XDocument doc = XDocument.Parse(header);
XElement sender = doc.Descendants().Where(x => x.Name.LocalName == "Sender").FirstOrDefault();
XNamespace shNs = sender.GetNamespaceOfPrefix("sh");
sender.Add(new XElement(shNs + "Identifier", new object[] {
new XAttribute("Authority", "GS1"),
"0000"
}));
sender.Add( new XElement(shNs + "ContactInformation", new object[] {
new XElement(shNs + "Contact", "some one"),
new XElement(shNs + "EmailAddress", "someone#example.com"),
new XElement(shNs + "TelephoneNumber", "00357"),
new XElement(shNs + "ContactTypeOdemtofier", "IT Support")
}));
}
}
}

how to send integer type data in xml

I am creating XML to send data. The data contains multiple datatypes as string, integer and decimal. My XML format and c# code to create it as follows.
<root>
<data>
<struct>
<PartnerCD></PartnerCD>
<UserName> </UserName>
<Password> </Password>
<Action> </Action>
<OfficeCD></OfficeCD>
<ChannelCD></ChannelCD>
<Token></Token>
<Notes> </Notes>
<Products>
<Product>
<ProductID></ProductID>
<SVA></SVA>
<Amount></Amount>
</Product>
</Products>
</struct>
</data>
</root>
And my c# code is
public static string CreateRequestXML(string partnerCd, string userName, string password, string action, string productId, string token, string sva, string amount)
{
XmlDocument doc = new XmlDocument();
XmlElement elemRoot = doc.CreateElement("root");
XmlElement elemData = doc.CreateElement("data");
XmlElement elemStruct = doc.CreateElement("struct");
XmlElement elemProducts = doc.CreateElement("Products");
XmlElement elemProduct = doc.CreateElement("Product");
doc.AppendChild(elemRoot);
elemRoot.AppendChild(elemData);
elemData.AppendChild(elemStruct);
//Insert data here
InsertDataNode(doc, elemStruct, "PartnerCD", partnerCd);
InsertDataNode(doc, elemStruct, "UserName", userName);
InsertDataNode(doc, elemStruct, "Password", password);
InsertDataNode(doc, elemStruct, "Action", action);
InsertDataNode(doc, elemStruct, "Token", token);
elemStruct.AppendChild(elemProducts);
elemProducts.AppendChild(elemProduct);
InsertDataNode(doc, elemProduct, "ProductID", productId);
InsertDataNode(doc, elemProduct, "SVA", sva);
InsertDataNode(doc, elemProduct, "Amount", amount);
return doc.OuterXml;
}
private static void InsertDataNode(XmlDocument doc, XmlElement parentElem, string nodeName, string nodeValue)
{
XmlElement elem = doc.CreateElement(nodeName);
elem.InnerText = nodeValue;
parentElem.AppendChild(elem);
}
and am getting the result as
<root>
<data>
<struct>
<PartnerCD>123</PartnerCD>
<UserName>api</UserName>
<Password>pass</Password>
<Action>token</Action>
<Token>4847898</Token>
<Products>
<Product>
<ProductID>123</ProductID>
<SVA>e8a8227c-bba3-4f32-a2cd-15e8f246344b</SVA>
<Amount>700</Amount>
</Product>
</Products>
</struct>
</data>
</root>
I want the PartnerCD and ProductId elements as integer and Amount element as decimal. I have tried XMLNodeType but no use.
Well the data type is irrelevant in the XML as such, it's all defined in the schema it uses, that's where the declaration of expected data types are stored.
So if you have a XSD that says that /root/data/struct/PartnerCD is of type xs:int then you will get validation errors upon validating the file. The XML itself is just a container of all data, it doesn't include the meta information. You CAN define it manually, but the Point is beyond me in about 99.99% of the cases, and it's more or less a bastard of XML, like MSXML that will understand what you're up to.
Xml has no concept of "data type" natively, the XmlNodeType you refer to is what type of Node it is (such as element, attribute etc), not what type of data is contained within it.
Personally I would create an object and Serialize\Deserialize to\from XML like so.....
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;
namespace _37321906
{
class Program
{
static void Main(string[] args)
{
Root root = new Root();
root.Data.Struct.PartnerCD = 123;
root.Data.Struct.UserName = "api";
root.Data.Struct.Password = "pass";
root.Data.Struct.Action = "token";
root.Data.Struct.Token = 4847898;
root.Data.Struct.Products.Product.Add(new Product { ProductID = 123, SVA = "e8a8227c-bba3-4f32-a2cd-15e8f246344b", Amount = 700.0001 });
// Serialize the root object to XML
Serialize<Root>(root);
// Deserialize from XML
Root DeserializeRoot = Deserialize<Root>();
}
private static 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 static 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));
}
}
[XmlRoot(ElementName = "Product")]
public class Product
{
[XmlElement(ElementName = "ProductID")]
public int ProductID { get; set; }
[XmlElement(ElementName = "SVA")]
public string SVA { get; set; }
[XmlElement(ElementName = "Amount")]
public double Amount { get; set; }
}
[XmlRoot(ElementName = "Products")]
public class Products
{
public Products()
{
this.Product = new List<Product>();
}
[XmlElement(ElementName = "Product")]
public List<Product> Product { get; set; }
}
[XmlRoot(ElementName = "struct")]
public class Struct
{
public Struct()
{
this.Products = new Products();
}
[XmlElement(ElementName = "PartnerCD")]
public int PartnerCD { get; set; }
[XmlElement(ElementName = "UserName")]
public string UserName { get; set; }
[XmlElement(ElementName = "Password")]
public string Password { get; set; }
[XmlElement(ElementName = "Action")]
public string Action { get; set; }
[XmlElement(ElementName = "OfficeCD")]
public string OfficeCD { get; set; }
[XmlElement(ElementName = "ChannelCD")]
public string ChannelCD { get; set; }
[XmlElement(ElementName = "Token")]
public int Token { get; set; }
[XmlElement(ElementName = "Notes")]
public string Notes { get; set; }
[XmlElement(ElementName = "Products")]
public Products Products { get; set; }
}
[XmlRoot(ElementName = "data")]
public class Data
{
public Data()
{
this.Struct = new Struct();
}
[XmlElement(ElementName = "struct")]
public Struct Struct { get; set; }
}
[XmlRoot(ElementName = "root")]
public class Root
{
public Root()
{
this.Data = new Data();
}
[XmlElement(ElementName = "data")]
public Data Data { get; set; }
}
}
find your XML in the build folder called test.xml

Prefixes and Namespaces with C# Objects

I am attempting to create a POST function that serialises C# class objects into XML.
The part I am having great difficulty with is adding namespace prefixes to the sub-root element's children, so in this instance, contact children only.
The only way I seem to be able to get the prefix onto the child elements of contactis to add them through SerializerNamespace class, however I can only get this to attach to the root element, CreateContact.
How can I achieve this?
XML Currently Produced:
<?xml version=\"1.0\"?>
<CreateContact xmlns:a="http://foo.co.uk/Contact" xmlns="http://foo.co.uk">
<a:contact>
<a:Email>stest#gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</a:contact>
</CreateContact>
Serialisation function:
public static void CreateContact(Contact contact)
{
string tmp = url;
string xml = "";
string result = "";
XmlDocument xd = new XmlDocument();
var cc = new CreateContact();
cc.contact = contact;
var xs = new XmlSerializer(cc.GetType());
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
using (MemoryStream ms = new MemoryStream())
{
xs.Serialize(ms, cc, xsn);
ms.Position = 0;
xd.Load(ms);
xml = xd.InnerXml;
}
using (WebClient web = new WebClient())
{
web.Credentials = new NetworkCredential(username, password);
web.Headers.Add("Content-Type", "application/xml");
try
{
result = web.UploadString(tmp, "POST", xml);
}
catch (WebException ex)
{
}
}
}
XML Class Constructs:
[Serializable()]
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact", Namespace = "http://foo.co.uk/Contact")]
public Contact contact { get; set; }
}
[DataContract(Name = "Contact", Namespace = "http://foo.co.uk/Contact")]
[XmlType("a")]
public class Contact
{
[XmlElement(ElementName = "Email", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Email")]
public string Email { get; set; }
[XmlElement(ElementName = "FirstName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "FirstName")]
public string Firstname { get; set; }
[XmlElement(ElementName = "LastName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "LastName")]
public string Lastname { get; set; }
[XmlElement(ElementName = "Phone", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Phone")]
public string Phone { get; set; }
[XmlElement(ElementName = "Title", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Title")]
public string Title { get; set; }
}
XML Desired:
<?xml version=\"1.0\"?>
<CreateContact xmlns="http://foo.co.uk">
<contact xmlns:a="http://foo.co.uk/Contact">
<a:Email>stest#gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</contact>
</CreateContact>
As alluded in the comments, the reason for the difference is that contact should be in the namespace http://foo.co.uk, not http://foo.co.uk/Contact.
As an aside, a couple of further comments:
You probably don't need the DataMember attributes, unless you're using DataContractSerializer somewhere else.
Most of the Xml* attributes are superfluous here, and could be removed or consolidated by inheriting from XmlRoot.
If all you need is the XML string, you'd be better off serialising to something like a StringWriter rather than to a stream and then loading into the DOM just to get the text (see this question if you need the XML declaration to specify utf-8)
So, you'd get the XML as below:
var xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
var xs = new XmlSerializer(typeof(CreateContact));
using (var stringWriter = new StringWriter())
{
xs.Serialize(stringWriter, cc, xsn);
xml = stringWriter.ToString();
}
With your classes defined as:
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact")]
public Contact Contact { get; set; }
}
[XmlRoot("contact", Namespace = "http://foo.co.uk/Contact")]
public class Contact
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Title { get; set; }
}
See this fiddle for the complete example.

Xml serialization c# enums only works on some computers

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

Unity C# ArrayList of Objects Serialize into XML Utf8 - Primitive Error

I have a ArrayList with some user objects in. I am trying to serialize them into an XML format that I can send to a webserver. The format needs to be UTF 8.
I keep running into this error:
The type of the argument object 'User' is not primitive.
This is effectively two issues, however the main one being that this primitive error will not let me try and other web examples for utf8. I simply to not understand why it does this. I have tried using:
[Serializable]
Currently I have a function which will work but it will not do the xml to a utf8 format. And when I try any other examples on the web I then get this primitive error. Below is my current code:
My User Class:
using System;
using System.Xml;
using System.Xml.Serialization;
[Serializable]
public class User
{
public int UserID { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public DateTime DateCreated { get; set; }
public string DeviceMacAddr { get; set; }
public DateTime LastLoggedIn { get; set; }
public float LastLoggedLat { get; set; }
public float LastLoggedLong { get; set; }
public bool Active { get; set; }
public string SyncStatus { get; set; }
public DateTime LastSyncDate { get; set; }
}
My XML writing Script:
using UnityEngine;
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
public class XmlWriting : MonoBehaviour {
private string formatString = "'yyyy'##'MM'##'dd' 'HH'*'mm'*'ss'";
[XmlAttribute("Users")]
ArrayList Users = new ArrayList();
//List<User> Users = new List<User>();
// Use this for initialization
void Start () {
Users.Add(new User { UserID = 1,
Name = "Test Woman",
Password = "aa",
DateCreated = DateTime.Now,
DeviceMacAddr = "24:70:8c:83:86:BD",
LastLoggedIn = DateTime.Now,
LastLoggedLat = 36.083101f,
LastLoggedLong = -11.263433f,
Active = true,
SyncStatus = "Awaiting Response",
LastSyncDate = DateTime.Now,
}
);
Users.Add(new User { UserID = 2,
Name = "Test Man",
Password = "aa",
DateCreated = DateTime.Now,
DeviceMacAddr = "74:21:0c:93:46:XD",
LastLoggedIn = DateTime.Now,
LastLoggedLat = 83.083101f,
LastLoggedLong = -3.261823f,
Active = true,
SyncStatus = "Complete",
LastSyncDate = DateTime.Now,
}
);
var serializer = new XmlSerializer(typeof(ArrayList));
var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream, System.Text.Encoding.UTF8);
serializer.Serialize(streamWriter, Users);
byte[] utf8EncodedXml = memoryStream.ToArray();
Debug.Log ("SerializeArrayList: " );//+ utf8EncodedXml);
}
// Update is called once per frame
void Update () {
}
private string SerializeArrayList(ArrayList obj)
{
XmlDocument doc = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(typeof(ArrayList), new Type[]{typeof(User)});
using (MemoryStream stream = new System.IO.MemoryStream())
{
try
{
serializer.Serialize(stream, obj);
stream.Position = 0;
doc.Load(stream);
Debug.Log ("stream: " + doc.InnerXml);
return doc.InnerXml;
}
catch (Exception ex)
{
}
}
return string.Empty;
}
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
}
}
Any help is much appreciated.
Thanks
You need to put the [Serializable] attribute above the class definitions for User and every other class you intend to serialize. As for UTF-8, it shouldn't matter, at least not logically - C#'s deserializer on the other side should handle any encoding transparently for you.

Categories