Deserializing with XML File - c#

I have been working on deserializing this xml document. I worked with a test document called note.xml which worked perfectly fine. However when I try to deserialize this file, I seem to not return anything. For example:
class Program
{
static void Main(string[] args)
{
try
{
string xml_path = "../../Family.xml";
//Console.WriteLine("Hello");
XmlSerializer x = new XmlSerializer(typeof(Families));
Families fam;
using (XmlReader read = XmlReader.Create(xml_path))
{
Console.WriteLine("read: " + read);
fam = (Families)x.Deserialize(read);
}
Console.WriteLine("This is " + fam);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.Read();
}
}
The code above does return the console.writeline("read: " + read) line but does not display the bottom console.writeline("This is " + fam). When i used Note.xml, it displayed both these lines indicating that the deserialize method worked. However, when i use Family.xml, only the first console.writeline() appears. Is there something i'm missing within my Family.xml that could be causing this to happen?
Here is the Family.xml file:
<?xml version="1.0" encoding="utf-8"?>
<Families>
<Family>
<FamilyID>23654</FamilyID>
<PostalAddress>
<MailingAddress1>54 The Companionway</MailingAddress1>
<MailingAddress2>Whitby</MailingAddress2>
<MailingCity>Porirua</MailingCity>
<MailingPostCode>5024</MailingPostCode>
</PostalAddress>
<ClientAddress>
<HomeAddress1>54 The Companionway</HomeAddress1>
<HomeAddress2>Whitby</HomeAddress2>
<HomeCity>Porirua</HomeCity>
<HomePostcode>5024</HomePostcode>
</ClientAddress>
<Family_Client>
<ClientID>4034</ClientID>
<Title>Mr</Title>
<FirstName>Anuj</FirstName>
<LastName>Hari</LastName>
<MiddleName>Kumar</MiddleName>
<PreferredName>Anuj</PreferredName>
<Email>anuj#nzfsg.co.nz</Email>
<Gender>Male</Gender>
<Dob>1992-10-14</Dob>
<HomePhone>2348070</HomePhone>
<MobilePhone>0276627137</MobilePhone>
<BusinessPhone></BusinessPhone>
<WorkEmail>anuj#nzfsg.co.nz</WorkEmail>
<Fax></Fax>
<Smoker>No</Smoker>
<BestTimeToCall></BestTimeToCall>
<Occupation></Occupation>
<Employer></Employer>
<Industry></Industry>
</Family_Client>
<Loan>
<LenderName>Abode Mortgages Limited</LenderName>
<LoanStatus>Conditional Approval</LoanStatus>
<LoanReferenceNumber>str1234</LoanReferenceNumber>
<DateCreated>2012-12-13</DateCreated>
<DateSettled>2012-12-13</DateSettled>
<DateSubmitted>2012-12-13</DateSubmitted>
<ApprovalDate>2012-12-13</ApprovalDate>
<DateDeclined>2012-12-13</DateDeclined>
<DateWithdrawn>2012-12-13</DateWithdrawn>
<DatePreApproved>2012-12-13</DatePreApproved>
<DatePreApprovalExpiry>2012-12-13</DatePreApprovalExpiry>
<DeferralReviewDate>2012-12-13</DeferralReviewDate>
<DateCancelled>2012-12-13</DateCancelled>
<Loan_Structure>
<LoanTerm>15</LoanTerm>
<InterestOnlyTerm>0</InterestOnlyTerm>
<FixedRateTerm></FixedRateTerm>
<FixedRateExpiryDate>2012-12-13</FixedRateExpiryDate>
<InterestRate>0.057</InterestRate>
<Amount>40000</Amount>
<LoanStructureType>Principal and Interest</LoanStructureType>
<RateType>Fixed</RateType>
<FrequencyName>Weekly</FrequencyName>
<PaymentAmount>500</PaymentAmount>
</Loan_Structure>
<Family_Client>
<ClientID>4034</ClientID>
</Family_Client>
</Loan>
UPDATE!
After i added Console.WriteLine(e.ToString()). It returned with about 20 lines of errors, the top line saying that the input string was not in the correct format.
The wanted Families class:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class Families {
private FamiliesFamily[] familyField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Family")]
public FamiliesFamily[] Family {
get {
return this.familyField;
}
set {
this.familyField = value;
}
}
}
And the FamiliesFamily class:
public partial class FamiliesFamily {
private int familyIDField;
private FamiliesFamilyPostalAddress postalAddressField;
private FamiliesFamilyClientAddress clientAddressField;
private FamiliesFamilyFamily_Client[] family_ClientField;
private FamiliesFamilyLoan[] loanField;
/// <remarks/>
public int FamilyID {
get {
return this.familyIDField;
}
set {
this.familyIDField = value;
}
}
/// <remarks/>
public FamiliesFamilyPostalAddress PostalAddress {
get {
return this.postalAddressField;
}
set {
this.postalAddressField = value;
}
}
/// <remarks/>
public FamiliesFamilyClientAddress ClientAddress {
get {
return this.clientAddressField;
}
set {
this.clientAddressField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Family_Client")]
public FamiliesFamilyFamily_Client[] Family_Client {
get {
return this.family_ClientField;
}
set {
this.family_ClientField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Loan")]
public FamiliesFamilyLoan[] Loan {
get {
return this.loanField;
}
set {
this.loanField = value;
}
}
}

So the issue was with in my Family.xml which is set to decimal so it's not allowed to return nothing. Not sure how i managed to overlook something so miniscule, but thanks to ekad who was looking in the right direction.

Related

Exception de-serializing SOAP XML into Object

I am developing a WCF Service that can accept and return SOAP 1.1 messages. However, I am having problems deserializing the SOAP body to my object. At the moment I have;
namespace MyAPI
{
[ServiceContract]
public interface IMyService
{
[OperationContract(IsOneWay = false, Action = "*", ReplyAction = "*")]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Xml)]
Message ProcessMessgae(Message message);
}
}
public class MyService : IMyService
{
public Message ProcessMessgae(Message message)
{
MessageBuffer buffer = message.CreateBufferedCopy(8192);
// Get a copy of the original message.
Message msgCopy = buffer.CreateMessage();
// Take another copy of the same message.
Message returnMsg = buffer.CreateMessage();
// Use the msgCopy to get an XML and extract the body contents. Once this message has been read and consumed,
System.Xml.XmlDictionaryReader xrdr = msgCopy.GetReaderAtBodyContents();
string bodyData = xrdr.ReadOuterXml();
var reader = new StringReader(bodyData);
var serializer = new XmlSerializer(typeof(OTA_HotelAvailRQ));
var instance = (OTA_HotelAvailRQ)serializer.Deserialize(reader);
return returnMsg;
}
}
This is my auto-generated object
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2046.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.opentravel.org/OTA/2003/05")]
public partial class OTA_HotelAvailRQ : object, System.ComponentModel.INotifyPropertyChanged
{
private string echoTokenField;
private System.DateTime timeStampField;
private bool timeStampFieldSpecified;
private bool targetFieldSpecified;
private decimal versionField;
private bool availRatesOnlyField;
private bool availRatesOnlyFieldSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string EchoToken
{
get
{
return this.echoTokenField;
}
set
{
this.echoTokenField = value;
this.RaisePropertyChanged("EchoToken");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public System.DateTime TimeStamp
{
get
{
return this.timeStampField;
}
set
{
this.timeStampField = value;
this.RaisePropertyChanged("TimeStamp");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool TimeStampSpecified
{
get
{
return this.timeStampFieldSpecified;
}
set
{
this.timeStampFieldSpecified = value;
this.RaisePropertyChanged("TimeStampSpecified");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal Version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
this.RaisePropertyChanged("Version");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public bool AvailRatesOnly
{
get
{
return this.availRatesOnlyField;
}
set
{
this.availRatesOnlyField = value;
this.RaisePropertyChanged("AvailRatesOnly");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool AvailRatesOnlySpecified
{
get
{
return this.availRatesOnlyFieldSpecified;
}
set
{
this.availRatesOnlyFieldSpecified = value;
this.RaisePropertyChanged("AvailRatesOnlySpecified");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null))
{
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
However, when I run the code I'm getting an exception on the following line var instance = (OTA_HotelAvailRQ)serializer.Deserialize(reader);
The SOAP XML I'm posting is;
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:UsernameToken>
<wsse:Username>test</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">thebest</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<OTA_HotelAvailRQ xmlns="http://www.opentravel.org/OTA/2003/05" Version="1.0" TimeStamp="2005-08-01T09:30:47+02:00" EchoToken="fb57388d" AvailRatesOnly="true">
</OTA_HotelAvailRQ>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The actual exception is;
What happens if you add your namespace to the xmlserializer?
var instance = (OTA_HotelAvailRQ)serializer.Deserialize(reader, "http://www.opentravel.org/OTA/2003/05");
Another option would be do something like the below, you may have to ReadOuterXml() instead of ReadInnerXml, the namespace may be able to be removed from this method too:
System.Xml.Linq.XElement body = System.Xml.Linq.XElement.Parse(msgCopy.GetReaderAtBodyContents().ReadInnerXml());
var instance = Deserialize<OTA_HotelAvailRQ>(body, "http://www.opentravel.org/OTA/2003/05");
public static T Deserialize<T>(XElement xElement, string nameSpace)
{
using (MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T), nameSpace);
return (T)xmlSerializer.Deserialize(memoryStream);
}
}
If you are still having problems, there is also a way using the DataContractSerializer or a SoapreflectionImporter, but you don't have a very complex object there those may be overkill.

Cant serialize a list of objects (each object contain a list) to xml

Im trying to understant how serialize works, but I have been stuck on a problem a while now.
What im trying to do is that I have a manager that handle a list of object. In this case recipe´s. In each recipe there is a list of ingredients. My manager is derived from a Listmanager class. The list of ingredients also uses the List manager class.
I have used this when I serialized a similar manager, except I serialized to binary (.dat). That worked and even worked with deserialize. I know xml is a bit different, but still worth mentioning..
The problem --> All I get is this when I serialize:
<?xml version="1.0"?>
<RecipeManager xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
I would like the xml-document to resemble something like this:
<Recipe>
<Name>Food<Name>
<Ingredient>blabla<Ingredient>
<Ingredient>blabla2<Ingredient>
<Ingredient>blabla3<Ingredient>
</Recipe>
This is my Listmanager, it has a bunch of other methods but this just so you can get an idea of how it looks:
[Serializable]
public class ListManager<T> : IListManager<T>
{
private List<T> list;
public ListManager()
{
list = new List<T>();
}
public int Count { get { return list.Count; } }
public void Add(T aType)
{
list.Add(aType);
}
public bool ChangeAt(T aType, int index)
{
if (CheckIndex(index))
{
list[index] = aType;
return true;
}
else
{
return false;
}
}
/// <summary>
/// Tittar så det finns ett objekt på platsen som användaren valt
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public bool CheckIndex(int index)
{
if (index < 0)
{
return false;
}
else if (list[index] != null)
{
return true;
}
else
return false;
}
This is my RecipeManager class:
[Serializable]
public class RecipeManager : ListManager<Recipe>
{
/// <summary>
/// Konstruktor
/// </summary>
public RecipeManager()
{
TestData();
}
private void TestData()
{
Recipe testInfo = new Recipe();
testInfo.Name = "AnimalSuperFood";
testInfo.IngredientsList.Add("2dl of water");
testInfo.IngredientsList.Add("3g of meat");
testInfo.IngredientsList.Add("1ml of lemon");
Add(testInfo);
}
}
This is my recipe class:
[Serializable]
[XmlRoot("Recipe")]
public class Recipe
{
#region props
private ListManager<string> ingredientsList;
[XmlArray("Ingredient")]
public ListManager<string> IngredientsList
{
get { return ingredientsList; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
#endregion
/// <summary>
/// Konstruktor
/// </summary>
public Recipe()
{
ingredientsList = new ListManager<string>();
}
public override string ToString()
{
string strOut = string.Format("{0}: ", Name); ;
for (int i = 0; i < IngredientsList.Count; i++)
{
if (i != (IngredientsList.Count - 1))
{
strOut += string.Format("{0} mixed with ", IngredientsList.GetAt(i));
}
else
{
strOut += string.Format("{0}", IngredientsList.GetAt(i));
}
}
return strOut;
}
}
This is where i send my manager that contains the objects:
using (SaveFileDialog dlg = new SaveFileDialog())
{
dlg.Title = "Save xml file";
dlg.Filter = "xml file (*.xml)|*.xml";
if (dlg.ShowDialog() == DialogResult.OK)
{
try
{
SerializationUtility.XmlFileSerialize(recipeMgr, dlg.FileName);
MessageBox.Show("Save succesful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
And last this is where i serialize:
public static void XmlFileSerialize<T>(T obj, string filePath)
{
using (Stream s = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
XmlSerializer xmlWriter = new XmlSerializer(typeof(T));
xmlWriter.Serialize(s, obj);
}
}
And last but not least, please explain why my question was bad if you Think so. dont just vote down and leave.. I am trying to learn.. thanks!
Ok, found your problem after re-reading the code: Any property you want to be serialized must be public.
Your "list" on ListManager is private, so it will not be serialized and there will be nothing.
Make it public and it will work.
Also any other private property/field you want to serialize must be public.

how can i use the file that is generated by xsd.exe in windows 10 universal app

I am generating .cs files from .xsd files using xsd.exe. But when I am adding the files to windows 10 universal blank app, I was getting error as "missing an assembly reference" for System.SerializableAttribute() and System.ComponentModel.DesignerCategoryAttribute(‌​"‌​code"). I fixed this by #t.ouvre's trick. Then there were no errors in any of the particular line of the code but when i am building the code i am getting an error saying that " Cannot find type System.ComponentModel.MarshalByValueComponent in module System.dll" and it doesn't specify exactly where the error is. How can I use the file generated by xsd.exe in windows 10 universal app? What are all the things that I need to do with the file to use it for serialization and deserialization (using DataContractSerializer in UWP)
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class request
{
private usertype userField;
private string versionField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public usertype user
{
get
{
return this.userField;
}
set
{
this.userField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class usertype
{
private string emailField;
private string passwordField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string email
{
get
{
return this.emailField;
}
set
{
this.emailField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string password
{
get
{
return this.passwordField;
}
set
{
this.passwordField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{
private request[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("request")]
public request[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}
You can fake missing classes (System.SerializableAttribute(),System.ComponentModel.DesignerCategoryAttribute), just add new files with theses classes definitions :
namespace System
{
internal class SerializableAttribute : Attribute
{
}
}
namespace System.ComponentModel
{
internal class DesignerCategoryAttribute : Attribute
{
public DesignerCategoryAttribute(string _) { }
}
}
for serialization and deserialization, you have to use System.Runtime.Serialization.DataContractSerializer. For example :
DataContractSerializer serializer = new DataContractSerializer(typeof(request));
var r = new request { version = "test" };
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, r);
ms.Seek(0, SeekOrigin.Begin);
using (var sr = new StreamReader(ms))
{
string xmlContent = sr.ReadToEnd();
Debug.WriteLine(xmlContent);
ms.Seek(0, SeekOrigin.Begin);
using (XmlReader reader = XmlReader.Create(sr))
{
var deserialized = serializer.ReadObject(reader) as request;
if (deserialized != null && deserialized.version == r.version)
{
Debug.WriteLine("ok");
}
}
}
}
SerializableAttribute()
and DesignerCategoryAttribute
aren't supported in the uwp apps.
To produce a successful class that can be copied directly into the UWP ap , use the following tip :
This is done in a UWP app so u can just go ahead and do this.
Well the XML serialization does have some limitations that is you must have a default constructor without any parameters.
if you are planing to serialize a class that doesn't have a constructor microsoft encourages to use DataContractSerializer for such use cases.
Now the code is quite simple
First instantiate the obj to serialize.
Make a new XmlSerializer object.
Then the XmlWriter obj , since it takes in many different writer classes and u Need to instantiate one i've chosen string builder for demo purposes.
Then just simply call serialize on the serializer obj passing in your obj and the xmlwriter and the xml writer produces the op in the string builder obj.
Then i just turn it into a string.. from here u can do anything with the xml .. save it or play with it ..
the last toUpper method was just added bcoz i needed a line for debug point .. it's not necessary at all ...
private void Button_Click( object sender , RoutedEventArgs e )
{
Animal a = new Animal("Sheep" , 4);
XmlSerializer m = new XmlSerializer(typeof(Animal));
StringBuilder op = new StringBuilder();
var x = XmlWriter.Create(op);
m.Serialize(x , a);
string s = op.ToString();
var p = s.ToUpper();
}
public class Animal
{
public Animal( string name , int legcount )
{
this.name = name;
this.legcount = legcount;
}
public Animal()
{
this.name = "default";
this.legcount = 10000000;
}
public string name { get; set; }
public int legcount { get; set; }
}
The reult of the Serialized class
<?xml version="1.0" encoding="utf-16"?>
<Animal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Sheep</name>
<legcount>4</legcount>
</Animal>
UPDATE: By this method you can first copy all of your serialized classes into the app and deserialize them when necessary inside the app.
Now all you need to do is copy your xml into ur new app and implement deserilization using the same techniques i've shown above.

Serialize an Enumeration to an XML Attribute

I'm generating >100 classes from a lot of XSD's to build our test harness application for internal testing. I'm using XSD.exe to generate these classes, as doing it by bring in too much risk and it would take way too long.
I'm having an issue that is causing me a bit of pain. I'm trying to get this enumeration (for now just this one, then I'll do the same technique on the remaining ones...)
What I would like is for this to generate something like this(where the receiver element has a typeCode attribute):
<receiver typeCode="RCV">
<device classCode="DEV" determinerCode="INSTANCE">
<id root="..." extension="..." />
<asAgent classCode="AGNT">
<representedOrganization classCode="ORG" determinerCode="INSTANCE">
<id root="..." extension="..." />
</representedOrganization>
</asAgent>
</device>
</receiver>
however, receiver never gets an attribute, even though I have explicetly set in the test harness startup object:
this.receiver = new MCCI_MT000100BCReceiver();
this.receiver.typeCode = CommunicationFunctionType.RSP;
this.receiver.device = new MCCI_MT000100BCDevice();
I have an enumeration (I've added the XMLEnums and the [Flags] attribute as XSD.exe didn't bother)
[Flags]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:hl7-org:v3")]
public enum CommunicationFunctionType
{
/// <remarks/>
[System.Xml.Serialization.XmlEnum("RCV")]
RCV = 1,
/// <remarks/>
[System.Xml.Serialization.XmlEnum("RSP")]
RSP = 2,
/// <remarks/>
[System.Xml.Serialization.XmlEnum("SND")]
SND = 3,
}
And this is one of the classes that use that enum:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "MCCI_MT000100BC.Receiver", Namespace = "urn:hl7-org:v3")]
public partial class MCCI_MT000100BCReceiver
{
private CS[] realmCodeField;
private II typeIdField;
private II[] templateIdField;
private MCCI_MT000100BCDevice deviceField;
private CommunicationFunctionType typeCodeField;
private bool typeCodeFieldSpecified;
public MCCI_MT000100BCReceiver()
{
this.typeCodeField = CommunicationFunctionType.RCV;
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("realmCode")]
public CS[] realmCode
{
get
{
return this.realmCodeField;
}
set
{
this.realmCodeField = value;
}
}
/// <remarks/>
public II typeId
{
get
{
return this.typeIdField;
}
set
{
this.typeIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("templateId")]
public II[] templateId
{
get
{
return this.templateIdField;
}
set
{
this.templateIdField = value;
}
}
/// <remarks/>
public MCCI_MT000100BCDevice device
{
get
{
return this.deviceField;
}
set
{
this.deviceField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public CommunicationFunctionType typeCode
{
get
{
return this.typeCodeField;
}
set
{
this.typeCodeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool typeCodeSpecified
{
get
{
return this.typeCodeFieldSpecified;
}
set
{
this.typeCodeFieldSpecified = value;
}
}
}
I understand that serializing enumerations isn't something .NET likes to do at times, but any help would be appreciated.
There is no problem with enums in .net/XML; the problem is simply that you (or xsd) have added a "typeCodeSpecified" member. This is a pattern that is used to conditionally include values - specifically, for a member called "Foo", the engine checks for either a "FooSpecified" property, or a "ShouldSerializeFoo()" method. Since you never set "typeCodeSpecified" to true, it will return false, and the member will be omitted during serialization.
If you didn't want that, remove this member.

XMLSerializer fails to deserialize a xml document

I am a newbie to C#. I have a java REST service which returns a xml response and I am trying to deserialize the xml document using C# XmlSerializer. A sample xml document response is pasted below.
<?xml version="1.0" encoding="UTF-8"
standalone="yes" ?> <ns2:Document
xmlns:ns2="http://hxps.honeywell.com/model/impl"
xmlns:ns3="http://hxps.honeywell.com/datatypes/impl"
type="PS">
<docId>SamplePSDocument1</docId>
<fields
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns5="http://jaxb.dev.java.net/array"
xsi:type="ns5:anyTypeArray"> <item
xsi:type="ns3:scalarFieldImpl"
key="Name">
<value xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:type="xs:string">HXPS A4</value>
</item> <item
xsi:type="ns3:scalarFieldImpl"
key="Creation Date">
<value xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:type="xs:string">20 April
2007</value> </item> </fields>
<id>fb92f871-1f3d-4fa4-ba24-5ae3af0a493f</id>
<revision>1-c75f688e212fb5341ebdbd22a3867c14</revision>
- <version> <majorVersionNumber>1</majorVersionNumber>
<minorVerisonNumber>5</minorVerisonNumber>
</version> </ns2:document>
It works fine when I deserialize this xml document into Document object. My document class is pasted below
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://hxps.honeywell.com/model/impl", TypeName = "PSDocument")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace = "http://hxps.honeywell.com/model/impl", TypeName = "PSDocument")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://hxps.honeywell.com/model/impl", ElementName = "Document")]
public partial class PSDocument
{
private Com.Honeywell.Hxps.Sdk.Model.DocumentType _type;
private string _description;
private string _displayName;
private string _docId;
private Com.Honeywell.Hxps.Sdk.Model.Impl.VersionImpl _version;
private object _fields;
private string _revision;
private string _id;
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName = "type")]
[System.Xml.Serialization.SoapAttributeAttribute(AttributeName = "type")]
public Com.Honeywell.Hxps.Sdk.Model.DocumentType Type
{
get
{
return this._type;
}
set
{
this._type = value;
}
}
/// <summary>
/// Property for the XML serializer indicating whether the "Type" property should be included in the output.
/// </summary>
[System.Xml.Serialization.XmlIgnoreAttribute]
[System.Xml.Serialization.SoapIgnoreAttribute]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public bool TypeSpecified
{
get
{
return this._type != Com.Honeywell.Hxps.Sdk.Model.DocumentType.NULL;
}
set
{
if (!value)
{
this._type = Com.Honeywell.Hxps.Sdk.Model.DocumentType.NULL;
}
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "description", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "description")]
public string Description
{
get
{
return this._description;
}
set
{
this._description = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "displayName", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "displayName")]
public string DisplayName
{
get
{
return this._displayName;
}
set
{
this._displayName = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "docId", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "docId")]
public string DocId
{
get
{
return this._docId;
}
set
{
this._docId = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "version", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "version")]
public Com.Honeywell.Hxps.Sdk.Model.Impl.VersionImpl Version
{
get
{
return this._version;
}
set
{
this._version = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "fields", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "fields")]
public object Fields
{
get
{
return this._fields;
}
set
{
this._fields = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "revision", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "revision")]
public string Revision
{
get
{
return this._revision;
}
set
{
this._revision = value;
}
}
/// <summary>
/// (no documentation provided)
/// </summary>
[System.Xml.Serialization.XmlElementAttribute(ElementName = "id", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "id")]
public string Id
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
}
}
In my main program, I get an array of xmlNodes when I try
Array fields = (Array)doc.Fields;
In the server side java REST service implementation, fields is actually a arraylist which will contain instances of three implementations of an interface. (List may contain ScalarFieldImpl or ArrayFieldImpl which are custom business objects).
I want to deserialize this xml fields into ScalarFieldImpl or ArrayFieldImpl using XmlSerializer. I want to know whether it is possible? If so, how do I do that?
As far as I know this isn't possible with the ootb xml (de-)serializer, I think you'll have to write your own XmlSerializer. Or try to use LINQ to XML.
I got this working. I did few changes in my PSDocument class.
private object _fields; -> private ArrayList _fields;
Also I changed get/set method and added new metadata
[System.Xml.Serialization.XmlArray(ElementName = "fields", Namespace = "")]
[System.Xml.Serialization.XmlArrayItem(ElementName="item")]
public ArrayList Fields
{
get
{
return this._fields;
}
set
{
this._fields = value;
}
}
Previously I had the following lines in my PSDocument class
[System.Xml.Serialization.XmlElementAttribute(ElementName = "fields", Namespace = "")]
[System.Xml.Serialization.SoapElementAttribute(ElementName = "fields")]
public object Fields
{
get
{
return this._fields;
}
set
{
this._fields = value;
}
}
So while deserializing fields in PSDocument, I get an arraylist with items as elements.
Hope this helps someone.

Categories

Resources