I have a XML as below. I want to convert this to c# object . I tried modyfying but could not get it working.
<SLVGeoZone-array>
<SLVGeoZone>
<id>19</id>
<type>geozone</type>
<name>60_OLC_SC</name>
<namesPath>GeoZones/60_OLC_SC</namesPath>
<idsPath>1/19</idsPath>
<childrenCount>0</childrenCount>
</SLVGeoZone>
</SLVGeoZone-array>
I have a written a sample c# code and it doesn't work:
[Serializable]
public class SLVGeoZone
{
[XmlElement("id")]
public string id { get; set; }
[XmlElement("type")]
public string type { get; set; }
[XmlElement("name")]
public string name { get; set; }
[XmlElement("namespath")]
public string namespath { get; set; }
[XmlElement("idspath")]
public string idspath { get; set; }
[XmlElement("childrencount")]
public string childrencount { get; set; }
}
[Serializable]
[XmlRoot("SLVGeoZone-array")]
public class SLVGeoZone-array
{
[XmlArray("SLVGeoZone-array")]
[XmlArrayItem("SLVGeoZone", typeof(SLVGeoZone))]
public SLVGeoZone[] Car { get; set; }
}
And in the form:
XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
StreamReader reader = new StreamReader(path);
cars = (CarCollection)serializer.Deserialize(reader);
reader.Close();
Can someone suggest what am i doing wrong?
SLVGeoZone-array is not a valid class name in C#
[Serializable()]
[XmlRoot("SLVGeoZone-array")]
public class SLVGeoZones
{
[XmlElement("SLVGeoZone")]
public SLVGeoZone[] Cars { get; set; }
}
XmlElement attribute values have to be exactly the same as element names in XML file. Yours are not.
[Serializable()]
public class SLVGeoZone
{
[XmlElement("id")]
public string id { get; set; }
[XmlElement("type")]
public string type { get; set; }
[XmlElement("name")]
public string name { get; set; }
[XmlElement("namesPath")]
public string namespath { get; set; }
[XmlElement("idsPath")]
public string idspath { get; set; }
[XmlElement("childrenCount")]
public string childrencount { get; set; }
}
What is CarCollection and why are you trying to deserialize your XML as CarCollection instead of classes you've shown here?
XmlSerializer serializer = new XmlSerializer(typeof(SLVGeoZones));
StreamReader reader = new StreamReader("Input.txt");
var items = (SLVGeoZones)serializer.Deserialize(reader);
reader.Close();
Related
I'm currently working on an application through WPF and wonder what's the better option in my case. I have a web based API that originally prints it's own XML and fills in the elements with it's data, but since this'll eventually be on a live server I thought it might seem a bit more convenient if the executable creates an XML file and parses API data into it.
If my option seems better, how do I write designated data to XML elements? I'm sorry if my question is a bit vague.
My JSON classes
[DataContract]
public class ShipmentDetails
{
[DataMember(Name="salutationCode")]
public string salutationCode { get; set; }
[DataMember(Name="firstName")]
public string firstName { get; set; }
[DataMember(Name="surName")]
public string surName { get; set; }
[DataMember(Name="streetName")]
public string streetName { get; set; }
[DataMember(Name="houseNumber")]
public string houseNumber { get; set; }
[DataMember(Name="zipCode")]
public string zipCode { get; set; }
[DataMember(Name="city")]
public string city { get; set; }
[DataMember(Name="countryCode")]
public string countryCode { get; set; }
[DataMember(Name="email")]
public string email { get; set; }
[DataMember(Name="language")]
public string language { get; set; }
}
[DataContract]
public class BillingDetails
{
[DataMember(Name="salutationCode")]
public string salutationCode { get; set; }
[DataMember(Name="firstName")]
public string firstName { get; set; }
[DataMember(Name="surName")]
public string surName { get; set; }
[DataMember(Name="streetName")]
public string streetName { get; set; }
[DataMember(Name="houseNumber")]
public string houseNumber { get; set; }
[DataMember(Name="zipCode")]
public string zipCode { get; set; }
[DataMember(Name="city")]
public string city { get; set; }
[DataMember(Name="countryCode")]
public string countryCode { get; set; }
[DataMember(Name="email")]
public string email { get; set; }
}
[DataContract]
public class CustomerDetails
{
[DataMember(Name="shipmentDetails")]
public ShipmentDetails shipmentDetails { get; set; }
[DataMember(Name="billingDetails")]
public BillingDetails billingDetails { get; set; }
}
[DataContract]
public class OrderItem
{
[DataMember(Name="orderItemId")]
public string orderItemId { get; set; }
[DataMember(Name="offerReference")]
public string offerReference { get; set; }
[DataMember(Name="ean")]
public string ean { get; set; }
[DataMember(Name="title")]
public string title { get; set; }
[DataMember(Name="quantity")]
public int quantity { get; set; }
[DataMember(Name="offerPrice")]
public double offerPrice { get; set; }
[DataMember(Name="offerId")]
public string offerId { get; set; }
[DataMember(Name="transactionFee")]
public double transactionFee { get; set; }
[DataMember(Name="latestDeliveryDate")]
public string latestDeliveryDate { get; set; }
[DataMember(Name="expiryDate")]
public string expiryDate { get; set; }
[DataMember(Name="offerCondition")]
public string offerCondition { get; set; }
[DataMember(Name="cancelRequest")]
public bool cancelRequest { get; set; }
[DataMember(Name="fulfilmentMethod")]
public string fulfilmentMethod { get; set; }
}
[DataContract]
public class Example
{
[DataMember(Name="orderId")]
public string orderId { get; set; }
[DataMember(Name="pickUpPoint")]
public bool pickUpPoint { get; set; }
[DataMember(Name="dateTimeOrderPlaced")]
public DateTime dateTimeOrderPlaced { get; set; }
[DataMember(Name="customerDetails")]
public CustomerDetails customerDetails { get; set; }
[DataMember(Name="orderItems")]
public IList<OrderItem> orderItems { get; set; }
}
My XML
using (XmlWriter writer = XmlWriter.Create("Orders.xml"))
{
writer.WriteStartElement("start");
writer.WriteElementString("customer_id", "935933");
writer.WriteStartElement("orders");
writer.WriteStartElement("order");
writer.WriteElementString("order_id", "");
writer.WriteElementString("order_ref", "");
writer.WriteElementString("order_dropshipment", "");
writer.WriteElementString("order_dlv_adr_name", "");
writer.WriteElementString("order_dlv_adr_street", "");
writer.WriteElementString("order_dlv_adr_housenr", "");
writer.WriteElementString("order_dlv_adr_zipcode", "");
writer.WriteElementString("order_dlv_adr_city", "");
writer.WriteElementString("order_dlv_adr_email", "");
writer.WriteElementString("order_dlv_adr_phone", "");
writer.WriteElementString("order_dlv_adr_country_isocode", "");
writer.WriteStartElement("orderrows");
writer.WriteStartElement("orderrow");
writer.WriteElementString("orderrow_sku", "");
writer.WriteElementString("orderrow_qty", "");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
}
XML mapping in PHP
$order->addChild('order_id',$info['orderId']);
$order->addChild('order_ref',$info['orderId']);// order_ref is usually the same as the order_id
$order->addChild('order_dropshipment',"Y"); // Yes and No if there's no dropshipment needed
$order->addChild('order_dlv_adr_name',$info['customerDetails']['shipmentDetails']['firstName'].' '.$info['customerDetails']['shipmentDetails']['surName']);
$order->addChild('order_dlv_adr_street',$info['customerDetails']['shipmentDetails']['streetName']);
$order->addChild('order_dlv_adr_housenr',$info['customerDetails']['shipmentDetails']['houseNumber']);
$order->addChild('order_dlv_adr_zipcode',$info['customerDetails']['shipmentDetails']['zipCode']);
$order->addChild('order_dlv_adr_city',$info['customerDetails']['shipmentDetails']['city']);
$order->addChild('order_dlv_adr_email',COMPANY_EMAIL);
$order->addChild('order_dlv_adr_phone',COMPANY_PHONE);
$order->addChild('order_dlv_adr_country_isocode',$info['customerDetails']['shipmentDetails']['countryCode']);
Desired output
<start>
<customer_id>935933</customer_id>
<orders>
<order>
<order_id>11864523</order_id>
<order_ref>11864523</order_ref>
<order_dropshipment>Y</order_dropshipment>
<order_dlv_adr_name>Fred Bellens</order_dlv_adr_name>
<order_dlv_adr_street>Elisabetaelaan</order_dlv_adr_street>
<order_dlv_adr_housenr>2</order_dlv_adr_housenr>
<order_dlv_adr_zipcode>3200</order_dlv_adr_zipcode>
<order_dlv_adr_city>Aarschot</order_dlv_adr_city>
<order_dlv_adr_email>*our mail*</order_dlv_adr_email>
<order_dlv_adr_phone>077 396 814</order_dlv_adr_phone>
<order_dlv_adr_country_isocode>BE</order_dlv_adr_country_isocode>
<orderrows>
<orderrow>
<orderrow_sku>KA0 14315 21_122</orderrow_sku>
<orderrow_qty>1</orderrow_qty>
</orderrow>
</orderrows>
</order>
</orders>
</start>
There are several ways how you can achieve that desired XML.
Let me show you two different ways:
XElement
Instead of relying on the XmlWriter we can construct the desired structure with XElement.
In your case the initialization of the tree could look similar to this:
var order = //...;
var shipment = order.customerDetails.billingDetails;
var xml = new XElement("start",
new XElement("customer_id", 935933),
new XElement("orders",
new XElement("order",
new XElement("order_id", order.orderId),
new XElement("order_ref", order.orderId),
new XElement("order_dropshipment", "Y"),
new XElement("order_dlv_adr_name", $"{shipment.firstName} {shipment.surName}"),
new XElement("order_dlv_adr_street", shipment.streetName),
new XElement("order_dlv_adr_housenr", shipment.houseNumber),
new XElement("order_dlv_adr_zipcode", shipment.zipCode),
new XElement("order_dlv_adr_city", shipment.city),
new XElement("order_dlv_adr_email", "TBD"),
new XElement("order_dlv_adr_phone", "TBD"),
new XElement("order_dlv_adr_country_isocode", shipment.countryCode)
)));
Then the persistence logic would look like this:
using var sampleXml = new FileStream("sample.xml", FileMode.CreateNew, FileAccess.Write);
using var fileWriter = new StreamWriter(sampleXml);
fileWriter.Write(xml.ToString());
fileWriter.Flush();
And that's it.
JsonConvert
As an alternative if you already have the desired structure in json then you can easily convert it to XML via JsonConvert's DeserializeXmlNode:
var orderInJson = JsonConvert.SerializeObject(data);
XmlDocument orderInXml = JsonConvert.DeserializeXmlNode(orderInJson);
And here is the persistence logic:
using var sampleXml = new XmlTextWriter("sample2.xml", Encoding.UTF8);
using var fileWriter = XmlWriter.Create(sampleXml);
orderInXml.WriteTo(fileWriter);
fileWriter.Flush();
Expected a nested document representing the serialized form of a Rootobject value, but found a value of type Array instead?
C# Code:
My guess is that I should write a custom serializer for that class but I couldn't find any useful example in the MONGODB .NET DRIVER Manual.
I'm working with C# MongoDB driver
string inputFileName = #"1546346582.07002.json"; // initialize to the input file
IMongoCollection<Rootobject> coll = database.GetCollection<Rootobject>("BB");
using (var streamReader = new StreamReader(inputFileName))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
using (var jsonReader = new MongoDB.Bson.IO.JsonReader(line))
{
var context = BsonDeserializationContext.CreateRoot(jsonReader);
var document = coll.DocumentSerializer.Deserialize(context);
coll.InsertOne(document);
}
}
}
public class Rootobject
{
[BsonElement ("Property1")]
public Class1[] Property1 { get; set; }
}
public class Class1
{
[BsonId]
public ObjectId _id { get; set; }
[BsonElement ("ID")]
public string account { get; set; }
[BsonElement ("Account")]
public string accuser { get; set; }
[BsonElement ("Accuser")]
public string bookedby { get; set; }
[BsonElement ("BookedBy")]
public bool changed { get; set; }
[BsonElement ("Changed")]
}
public class Fromtovia
{
public string info { get; set; }
[BsonElement ("Info")]
public string address { get; set; }
[BsonElement("Address")]
public float lat { get; set; }
[BsonElement("Latitude")]
public float lon { get; set; }
[BsonElement("longitude")]
public string postcode { get; set; }
}
But I couldn't find anything Useful.
I want to deserialize an XML string to an object. the execution don't return an error or an exception. I search in net but don't find any solution that I can apply to my issue.
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Get_mouvements_usersResult";
xRoot.Namespace = "urn:DME_Webservices";
xRoot.IsNullable = false;
trueObject="<ns1:Get_mouvements_usersResult xmlns:ns1=\"urn:DME_Webservices\"><Obj_info_retour><flag_erreur>false</flag_erreur><libelle_erreur/><libelle_detail_erreur/></Obj_info_retour><tab_Cuser_mouvements><obj_cuser><IPP>02084</IPP><Id_user>4503843842</Id_user><civilite>Mme</civilite><nom_usuel>BOTTU</nom_usuel><nom_naissance>LOACU</nom_naissance><prenom>Alida</prenom><date_naissance>19340707</date_naissance><numro_sejour>31202084001</numro_sejour><date_deb_sejour>20150420113700</date_deb_sejour><code_lit>504</code_lit><code_etablissement>000312</code_etablissement></obj_cuser><tab_obj_Cmouvement>Id_mouvement>4505631384</Id_mouvement><date_mouvement>20150420113700</date_mouvement><code_mouvement>E</code_mouvement><Libelle_mouvement>Entre tablissement</Libelle_mouvement><code_ufh>ETG1</code_ufh><libelle_ufh>Etage 1-Chteau de Fermaincourt</libelle_ufh><code_ufm>SSR_HC_CONVA</code_ufm><libelle_ufm>Convalescence</libelle_ufm><Date_fin_mouvement>20150422152600</Date_fin_mouvement><code_lit>402</code_lit><comm_mouvement/>/tab_obj_Cmouvement><tab_obj_Cmouvement><Id_mouvement>4533166359</Id_mouvement><date_mouvement>20150422152600</date_mouvement><code_mouvement>M</code_mouvement><Libelle_mouvement>Mutation</Libelle_mouvement>code_ufh>ETG3</code_ufh><libelle_ufh>Etage 3 - La Chapelle Royale</libelle_ufh><code_ufm>SSR_HC_CONVA</code_ufm><libelle_ufm>Convalescence</libelle_ufm><Date_fin_mouvement>20150730142100</Date_fin_mouvement>code_lit>605D</code_lit><comm_mouvement/></tab_obj_Cmouvement><tab_obj_Cmouvement><Id_mouvement>5125097053</Id_mouvement><date_mouvement>20150730142100</date_mouvement><code_mouvement>M</code_mouvement><Libelle_mouvement>Mutation</Libelle_mouvement><code_ufh>ETG2</code_ufh><libelle_ufh>Etage 2 - Domaine de Comteville</libelle_ufh><code_ufm>SSR_HC_SDSG</code_ufm><libelle_ufm>Griatrie</libelle_ufm><Date_fin_mouvement/><code_lit>504</code_lit><comm_mouvement/></tab_obj_Cmouvement></tab_Cuser_mouvements></ns1:Get_mouvements_usersResult>";
MemoryStream stream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(trueObject));
XmlSerializer serializer = new XmlSerializer(typeof(XmlUsers), xRoot);
listXmlUserMove = (XmlUsers)serializer.Deserialize(stream);
I have these classes:
[Serializable, XmlRoot("ns1:Get_mouvements_usersResult"), XmlType("ns1:Get_mouvements_usersResult")]
public class XmlUsers
{
[XmlElement("tab_Cuser_mouvements")]
public List<XmlUserMove> UserList { get; set; }
[XmlElement("Obj_info_retour")]
public SoapResult soapResult { get; set; }
}
[XmlType("Obj_info_retour")]
public class SoapResult
{
[XmlElement("flag_erreur")]
public string ErrorFlag { get; set; }
[XmlElement("libelle_erreur")]
public string ErrorName { get; set; }
[XmlElement("libelle_detail_erreur")]
public string ErrorDetails { get; set; }
}
[XmlType("tab_Cuser_mouvements")]
public class XmlUserMove
{
[XmlElement("obj_cuser")]
public XmlUser user { get; set; }
[XmlElement("tab_obj_Cmouvement")]
public List<XmlMove> MoveList { get; set; }
}
public class XmlUser
{
[XmlElementAttribute("IPP")]
public string IPP { get; set; }
[XmlElementAttribute("Id_patient")]
public string IdUser { get; set; }
[XmlElementAttribute("civilite")]
public string Title { get; set; }
[XmlElementAttribute("nom_usuel")]
public string UsedLastName { get; set; }
[XmlElementAttribute("nom_naissance")]
public string BirthLastName { get; set; }
[XmlElementAttribute("prenom")]
public string FirstName { get; set; }
[XmlElementAttribute("date_naissance")]
public string Birthday { get; set; }
[XmlElementAttribute("numero_sejour")]
public string RoomNumber { get; set; }
[XmlElementAttribute("date_deb_sejour")]
public string EntredDate { get; set; }
[XmlElementAttribute("code_lit")]
public string BedCode { get; set; }
[XmlElementAttribute("code_etablissement")]
public string DivisionCode { get; set; }
}
public class XmlMove
{
[XmlElement("Id_mouvement")]
public string MoveId { get; set; }
[XmlElement("date_mouvement")]
public string MoveDate { get; set; }
[XmlElement("code_mouvement")]
public string MoveCode { get; set; }
[XmlElement("Libelle_mouvement")]
public string MoveName { get; set; }
[XmlElement("code_ufh")]
public string ufhCode { get; set; }
[XmlElement("libelle_ufh")]
public string UfhName { get; set; }
[XmlElement("code_ufm")]
public string UfmCode { get; set; }
[XmlElement("libelle_ufm")]
public string UfmName { get; set; }
[XmlElement("Date_fin_mouvement")]
public string MoveEndDate { get; set; }
[XmlElement("code_lit")]
public string BedCode { get; set; }
[XmlElement("comm_mouvement")]
public string MoveComm { get; set; }
}
The listXmlUserMove object don't contain anything but the xml contain many things.
Any one can help me please?
There are a few < characters missing from your trueObject, and you didn't include the XmlUser class, but since you reported an empty object and not an exception, I'm assuming what you have is really ok, and that was just a copy/paste error.
You don't need to declare the xRoot object separately if you get the attributes on XmlUsers set up correctly. ns1 is meaningless without context. You should use the Namespace property to give the info to those attributes correctly.
[Serializable, XmlRoot("Get_mouvements_usersResult", Namespace = "urn:DME_Webservices"), XmlType("Get_mouvements_usersResult", Namespace = "urn:DME_Webservices")]
public class XmlUsers
Your elements aren't coming through because of a namespace issue. XmlUsers's Namespace is assumed to apply to the elements inside of it. In your actual XML, though, they are in a different namespace. Since they have no xmlns defined, they're in the default namespace, an empty string. The element's namespaces should be set explicitly:
[Serializable, XmlRoot("Get_mouvements_usersResult", Namespace = "urn:DME_Webservices"), XmlType("Get_mouvements_usersResult", Namespace = "urn:DME_Webservices")]
public class XmlUsers
{
[XmlElement("tab_Cuser_mouvements", Namespace = "")]
public List<XmlUserMove> UserList { get; set; }
[XmlElement("Obj_info_retour", Namespace = "")]
public SoapResult soapResult { get; set; }
}
If you had intended everything to be inside ns1, then you'll need to rework your XML files and classes to match that.
So now the code to deserialize looks like this (note, this includes my fixed trueObject string)
var trueObject="<ns1:Get_mouvements_usersResult xmlns:ns1=\"urn:DME_Webservices\"><Obj_info_retour><flag_erreur>false</flag_erreur><libelle_erreur/><libelle_detail_erreur/></Obj_info_retour><tab_Cuser_mouvements><obj_cuser><IPP>02084</IPP><Id_user>4503843842</Id_user><civilite>Mme</civilite><nom_usuel>BOTTU</nom_usuel><nom_naissance>LOACU</nom_naissance><prenom>Alida</prenom><date_naissance>19340707</date_naissance><numro_sejour>31202084001</numro_sejour><date_deb_sejour>20150420113700</date_deb_sejour><code_lit>504</code_lit><code_etablissement>000312</code_etablissement></obj_cuser><tab_obj_Cmouvement><Id_mouvement>4505631384</Id_mouvement><date_mouvement>20150420113700</date_mouvement><code_mouvement>E</code_mouvement><Libelle_mouvement>Entre tablissement</Libelle_mouvement><code_ufh>ETG1</code_ufh><libelle_ufh>Etage 1-Chteau de Fermaincourt</libelle_ufh><code_ufm>SSR_HC_CONVA</code_ufm><libelle_ufm>Convalescence</libelle_ufm><Date_fin_mouvement>20150422152600</Date_fin_mouvement><code_lit>402</code_lit><comm_mouvement/></tab_obj_Cmouvement><tab_obj_Cmouvement><Id_mouvement>4533166359</Id_mouvement><date_mouvement>20150422152600</date_mouvement><code_mouvement>M</code_mouvement><Libelle_mouvement>Mutation</Libelle_mouvement><code_ufh>ETG3</code_ufh><libelle_ufh>Etage 3 - La Chapelle Royale</libelle_ufh><code_ufm>SSR_HC_CONVA</code_ufm><libelle_ufm>Convalescence</libelle_ufm><Date_fin_mouvement>20150730142100</Date_fin_mouvement><code_lit>605D</code_lit><comm_mouvement/></tab_obj_Cmouvement><tab_obj_Cmouvement><Id_mouvement>5125097053</Id_mouvement><date_mouvement>20150730142100</date_mouvement><code_mouvement>M</code_mouvement><Libelle_mouvement>Mutation</Libelle_mouvement><code_ufh>ETG2</code_ufh><libelle_ufh>Etage 2 - Domaine de Comteville</libelle_ufh><code_ufm>SSR_HC_SDSG</code_ufm><libelle_ufm>Griatrie</libelle_ufm><Date_fin_mouvement/><code_lit>504</code_lit><comm_mouvement/></tab_obj_Cmouvement></tab_Cuser_mouvements></ns1:Get_mouvements_usersResult>";
MemoryStream stream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(trueObject));
XmlSerializer serializer = new XmlSerializer(typeof(XmlUsers));
var listXmlUserMove = (XmlUsers)serializer.Deserialize(stream);
But the object is actually populated at the end!
I do what Tim S. tell me but I don't remove the xRoot :
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Get_mouvements_usersResult";
xRoot.Namespace = "urn:DME_Webservices";
xRoot.IsNullable = false;
.
XmlSerializer serializer = new XmlSerializer(typeof(XmlUsers), xRoot);
Now the solution work fine.
Thank you for your help :)
I am trying to serialize an object to xml, and I have the error below:
: Could Not Serialize object to .\Sample.xml
The inner exception is:
There was an error reflecting type 'SiteProvisioningFramework.Entities.SiteDefinition'.
The serializing code is:
static void Main(string[] args)
{
var siteDefinition = new SiteDefinition();
siteDefinition.Name = "ContosoIntranet";
siteDefinition.Version = "1.0.0.0";
siteDefinition.MasterPages = new List<SiteProvisioningFramework.MasterPage>()
{
new MasterPage(){
Name="seattle.master",
ServerFolder ="_catalogs/ContosoIntranet/",
UIVersion = "15",
Url="",
LocalFolder = ".MasterPages/seattle.master"
}
};
Utilities.XmlHelper.ObjectToXml(siteDefinition, #".\Sample.xml");
}
public static void ObjectToXml(object obj, string path_to_xml)
{
//serialize and persist it to it's file
try
{
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(obj.GetType());
FileStream fs = File.Open(
path_to_xml,
FileMode.OpenOrCreate,
FileAccess.Write,
FileShare.ReadWrite);
ser.Serialize(fs, obj);
}
catch (Exception ex)
{
throw new Exception(
"Could Not Serialize object to " + path_to_xml,
ex);
}
}
The classes are:
public class SiteDefinition
{
[XmlAttribute ()]
public string Name { get; set; }
[XmlAttribute()]
public string Version { get; set; }
public List<MasterPage> MasterPages { get; set; }
public List<File> Files { get; set; }
public List<PageLayout> PageLayouts { get; set; }
public List<Feature> Features { get; set; }
public List<ContentType> ContentTypes { get; set; }
public List<StyleSheet> StyleSheets { get; set; }
}
public class MasterPage : File
{
[XmlAttribute()]
public string UIVersion { get; set; }
[XmlAttribute()]
public string MasterPageDescription { get; set; }
}
public class File
{
[XmlAttribute()]
public string Url { get; set; }
[XmlAttribute()]
public string Name { get; set; }
[XmlAttribute()]
public string LocalFolder { get; set; }
[XmlAttribute()]
public string ServerFolder { get; set; }
}
public class Field
{
public string Guid { get; set; }
public string Name { get; set; }
public string GroupName { get; set; }
}
public class Feature
{
public string Guid { get; set; }
}
public class ContentType
{
public string Guid { get; set; }
public string Name { get; set; }
public string GroupName { get; set; }
public List<Field> Fields { get; set; }
}
public class List
{
public List<ContentType> ContentTypes { get; set; }
public string Name { get; set; }
}
public class PageLayout : File
{
public string UIVersion { get; set; }
public string MasterPageDescription { get; set; }
}
public class StyleSheet : File
{
public string Name { get; set; }
}
public class Theme
{
public string Name { get; set; }
public string ColorFilePath { get; set; }
public string FontFilePath { get; set; }
public string BackgroundImagePath { get; set; }
public MasterPage MasterPage { get; set; }
}
any idea?
The error lies with one property in your SiteDefinition class -
public List<ContentType> ContentTypes { get; set; }
A System.Net.Mime.ContentType apparently can't be serialized. If you put an XmlIgnore attribute on it, the code runs fine.
[XmlIgnore]
public List<ContentType> ContentTypes { get; set; }
Edit:
Your ContentType is a custom class - so that is not it. But your Name property in your StyleSheet class is hiding the exact same property in the class that it inherits from (File) - this is causing the serialization error.
I am trying to deserialize the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<id>750x0000000005LAAQ</id>
<operation>insert</operation>
<object>Contact</object>
<createdById>005x0000000wPWdAAM</createdById>
<createdDate>2009-09-01T16:42:46.000Z</createdDate>
<systemModstamp>2009-09-01T16:42:46.000Z</systemModstamp>
<state>Open</state>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
<numberBatchesQueued>0</numberBatchesQueued>
<numberBatchesInProgress>0</numberBatchesInProgress>
<numberBatchesCompleted>0</numberBatchesCompleted>
<numberBatchesFailed>0</numberBatchesFailed>
<numberBatchesTotal>0</numberBatchesTotal>
<numberRecordsProcessed>0</numberRecordsProcessed>
<numberRetries>0</numberRetries>
<apiVersion>28.0</apiVersion>
</jobInfo>
I have created this object:
public class JobInfo
{
public string xmlns { get; set; }
public string id { get; set; }
public string operation { get; set; }
public string #object { get; set; }
public string createdById { get; set; }
public string createdDate { get; set; }
public string systemModstamp { get; set; }
public string state { get; set; }
public string concurrencyMode { get; set; }
public string contentType { get; set; }
public string numberBatchesQueued { get; set; }
public string numberBatchesInProgress { get; set; }
public string numberBatchesCompleted { get; set; }
public string numberBatchesFailed { get; set; }
public string numberBatchesTotal { get; set; }
public string numberRecordsProcessed { get; set; }
public string numberRetries { get; set; }
public string apiVersion { get; set; }
}
public class RootObject
{
public JobInfo jobInfo { get; set; }
}
And, I am using this code:
XmlSerializer serializer = new XmlSerializer(typeof(RootObject));
StringReader rdr = new StringReader(response);
RootObject resultingMessage = (RootObject)serializer.Deserialize(rdr);
However, I get this error:
There is an error in XML document (1, 40).
{"<jobInfo xmlns='http://www.force.com/2009/06/asyncapi/dataload'> was not expected."}
How can I account for the xmlns attribute? My code has it as a property (thus, it fails)...
Currently your code is expecting the xmlns as element, not the attribute.
You should add the XmlSerialization attributes to your class, like this:
[XmlRoot("jobInfo", Namespace="http://www.force.com/2009/06/asyncapi/dataload"]
public class JobInfo
{
[XmlAttribute]
public string xmlns { get; set; }
[XmlElement(ElementName = "id")]
public string id { get; set; }
....
}
You can find more information in MSDN articles:
Controlling XML Serialization Using Attributes
Examples of XML Serialization
Try using the XmlRootAttribute to specify the Namespace.
[XmlRoot("jobInfo", Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
public class JobInfo
{
[XmlElement("id")]
public string Id { get; set; }
[XmlElement("operation")]
public string Operation { get; set; }
[XmlElement("object")]
public string Object { get; set; }
[XmlElement("createdById")]
public string CreatedById { get; set; }
[XmlElement("createdDate")]
public DateTime CreatedDate { get; set; }
[XmlElement("systemModstamp")]
public DateTime SystemModstamp { get; set; }
[XmlElement("state")]
public string State { get; set; }
[XmlElement("concurrencyMode")]
public string ConcurrencyMode { get; set; }
[XmlElement("contentType")]
public string ContentType { get; set; }
[XmlElement("numberBatchesQueued")]
public string NumberBatchesQueued { get; set; }
[XmlElement("numberBatchesInProgress")]
public string NumberBatchesInProgress { get; set; }
[XmlElement("numberBatchesCompleted")]
public string NumberBatchesCompleted { get; set; }
[XmlElement("numberBatchesFailed")]
public string NumberBatchesFailed { get; set; }
[XmlElement("numberBatchesTotal")]
public string NumberBatchesTotal { get; set; }
[XmlElement("numberRecordsProcessed")]
public string numberRecordsProcessed { get; set; }
[XmlElement("numberRetries")]
public string NumberRetries { get; set; }
[XmlElement("apiVersion")]
public string ApiVersion { get; set; }
}
Code:
var xml = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<jobInfo xmlns=""http://www.force.com/2009/06/asyncapi/dataload"">
<id>750x0000000005LAAQ</id>
<operation>insert</operation>
<object>Contact</object>
<createdById>005x0000000wPWdAAM</createdById>
<createdDate>2009-09-01T16:42:46.000Z</createdDate>
<systemModstamp>2009-09-01T16:42:46.000Z</systemModstamp>
<state>Open</state>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
<numberBatchesQueued>0</numberBatchesQueued>
<numberBatchesInProgress>0</numberBatchesInProgress>
<numberBatchesCompleted>0</numberBatchesCompleted>
<numberBatchesFailed>0</numberBatchesFailed>
<numberBatchesTotal>0</numberBatchesTotal>
<numberRecordsProcessed>0</numberRecordsProcessed>
<numberRetries>0</numberRetries>
<apiVersion>28.0</apiVersion>
</jobInfo>";
var serializer = new XmlSerializer(typeof(JobInfo));
JobInfo jobInfo;
using(var stream = new StringReader(xml))
using(var reader = XmlReader.Create(stream))
{
jobInfo = (JobInfo)serializer.Deserialize(reader);
}
Add the namespace
[XmlRoot("jobInfo",Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
public class JobInfo
{
// get rid of the xmlns property
// other properties stay
}
// there is no rootobject, JobInfo is your root
XmlSerializer serializer = new XmlSerializer(typeof(JobInfo));
StringReader rdr = new StringReader(response);
JobInfo resultingMessage = (JobInfo)serializer.Deserialize(rdr);