How to serialize custom SOAP for OTRS - c#

There is a WSDL scheme for SOAP in OTRS, unfortunately with an automaton (connecting links), it does not work, because Sharp considers the file to be incorrect. for normal operation, you must obtain the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tic="http://www.otrs.org/TicketConnector/">
<soapenv:Header/>
<soapenv:Body>
<SessionCreate>
<tic:UserLogin>ULogin</tic:UserLogin>
<tic:CustomerUserLogin>CustUser</tic:CustomerUserLogin>
<tic:Password>ULPassword</tic:Password>
</SessionCreate>
</soapenv:Body>
</soapenv:Envelope>
I tried through System.Runtime.Serialization.Formatters.Soap as follows:
[Serializable]
public partial class Envelope
{
/// <remarks/>
public object Header { get; set; }
/// <remarks/>
public EnvelopeBody Body { get; set; }
}
[Serializable]
public partial class EnvelopeBody
{
public SessionCreate SessionCreate { get; set; }
}
[Serializable]
[System.Xml.Serialization.SoapType(IncludeInSchema =true, Namespace = "")]
public partial class SessionCreate
{
/// <remarks/>
[System.Xml.Serialization.SoapElement("http://www.otrs.org/TicketConnector/")]
public string UserLogin { get; set; }
/// <remarks/>
[System.Xml.Serialization.SoapElement("http://www.otrs.org/TicketConnector/")]
public string CustomerUserLogin { get; set; }
/// <remarks/>
[System.Xml.Serialization.SoapElement("http://www.otrs.org/TicketConnector/")]
public string Password { get; set; }
}
class TEST
{
void GetSoap()
{
var model = new SessionCreate
{
UserLogin ="ULogin",
CustomerUserLogin="CustUser",
Password="ULPassword"
};
var en = new Envelope
{
Body = new EnvelopeBody
{
SessionCreate = model
}
};
SoapFormatter formatter = new SoapFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms, en);
Console.WriteLine(StreamToString(ms));
}
string StreamToString(Stream stream)
{
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
As a result, it displays the following:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:Envelope id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/OTRS.Request/OTRS%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_Header_x003E_k__BackingField xsi:type="xsd:anyType" xsi:null="1"/>
<_x003C_Body_x003E_k__BackingField href="#ref-3"/>
</a1:Envelope>
<a1:EnvelopeBody id="ref-3" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/OTRS.Request/OTRS%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_SessionCreate_x003E_k__BackingField href="#ref-4"/>
</a1:EnvelopeBody>
<a1:SessionCreate id="ref-4" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/OTRS.Request/OTRS%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_UserLogin_x003E_k__BackingField id="ref-5">ULogin</_x003C_UserLogin_x003E_k__BackingField>
<_x003C_CustomerUserLogin_x003E_k__BackingField id="ref-6">CustUser</_x003C_CustomerUserLogin_x003E_k__BackingField>
<_x003C_Password_x003E_k__BackingField id="ref-7">ULPassword</_x003C_Password_x003E_k__BackingField>
</a1:SessionCreate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The question arises, how to do it normally, and what am I doing wrong?

Related

In C#, how can I serialize a POCO to XML with a lot of fancy markup?

To consume a SOAP service, I need to send messages in XML which looks like:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bus="http://ws.praxedo.com/v6/businessEvent">
<soap:Header/>
<soap:Body>
<bus:listAttachments>
<businessEventId>00044</businessEventId>
</bus:listAttachments>
</soap:Body>
</soap:Envelope>
Obviously, the easy way to do this would just be to create a string and interpolate some variable (e.g. businessEventId) into the midst of it, like:
$"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\""
+ " xmlns:bus=\"http://ws.praxedo.com/v6/businessEvent\">"
+ "<soap:Header/><soap:Body>"
+ "<bus:listAttachments><businessEventId>{businessEventId}</businessEventId>"
+ "</bus:listAttachments></soap:Body></soap:Envelope>"
But I'd rather instantiate some collection of POPO, like:
public class Envelope {
public Header Header {get; init;}
public Body Body {get; init;}
}
public class Header {
}
public class Body {
public ListAttachments Attachments {get; init;}
}
public class ListAttachments {
public string BusinessEventId {get; init;}
}
What Attributes do I need to declare?
And what would I then need to do to serialize this, assuming I have a populated instance already?
--
As per #DavidBrowne's comment, I've tried the following which does NOT work:
private string CreateBody(string businessEventId)
{
BusinessEventAttachmentListRequestEnvelope envelope = BusinessEventAttachmentListRequestEnvelope.From(businessEventId);
MemoryStream memorystream = new();
DataContractSerializer serializer = new(typeof(BusinessEventAttachmentListRequestEnvelope));
serializer.WriteObject(memorystream, envelope);
memorystream.Seek(0, SeekOrigin.Begin);
using StreamReader streamReader = new(memorystream);
return streamReader.ReadToEnd();
}
[DataContract(Name = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestEnvelope
{
[DataMember]
EmptySoapHeader Header = new();
[DataMember]
BusinessEventAttachmentListRequestBody Body { get; init; }
public static BusinessEventAttachmentListRequestEnvelope From(string businessEventId) =>
new()
{
Body = new()
{
Request = new()
{
BusinessEventId = businessEventId
}
}
};
}
[DataContract(Name = "Header", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class EmptySoapHeader
{
}
[DataContract(Name = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestBody
{
[DataMember(Name = "listAttachments")]
public BusinessEventAttachmentListRequest Request { get; init; }
}
[DataContract(Name = "listAttachments", Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public class BusinessEventAttachmentListRequest
{
[DataMember(Name = "businessEventId")]
public string BusinessEventId { get; init; }
}
The resulting XML seems substantially different:
<Envelope xmlns=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">
<Body>
<listAttachments xmlns:a=\"http://ws.praxedo.com/v6/businessEvent\">
<a:businessEventId>00044</a:businessEventId>
</listAttachments>
</Body>
<Header/>
</Envelope>
And the remote server returns error 500.
If you're using Visual Studio there's a really easy shortcut you can use: Paste XML as Classes:
Which creates for your sample XML:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
public partial class Envelope
{
private object headerField;
private EnvelopeBody bodyField;
/// <remarks/>
public object Header
{
get
{
return this.headerField;
}
set
{
this.headerField = value;
}
}
/// <remarks/>
public EnvelopeBody Body
{
get
{
return this.bodyField;
}
set
{
this.bodyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeBody
{
private listAttachments listAttachmentsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public listAttachments listAttachments
{
get
{
return this.listAttachmentsField;
}
set
{
this.listAttachmentsField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.praxedo.com/v6/businessEvent")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent", IsNullable = false)]
public partial class listAttachments
{
private byte businessEventIdField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "")]
public byte businessEventId
{
get
{
return this.businessEventIdField;
}
set
{
this.businessEventIdField = value;
}
}
}

C# XmlSerializer define namespace with prefix in a child node

I need to create an XML document with C# that is like this:
<?xml version="1.0" encoding="utf-8"?>
<Container>
<Info>
<request xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
<a:AuthenticationToken>token</a:AuthenticationToken>
<a:Username>username</a:Username>
<a:ConsignmentNumber>12345</a:ConsignmentNumber>
</request>
</Info>
</Container>
The critical part is the namespace definition with a prefix (xmlns:a=...) is in a child node, not the root node. I have only been able to produce this document so far:
<?xml version="1.0" encoding="utf-8"?>
<Container xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
<Info>
<a:request>
<a:AuthenticationToken>token</a:AuthenticationToken>
<a:Username>username</a:Username>
<a:ConsignmentNumber>12345</a:ConsignmentNumber>
</a:request>
</Info>
</Container>
This is rejected by the web service - if you move the xmlns:a.. part to the request node the web service is happy with it.
This is how I am generating the XML at the moment:
class Program
{
static void Main(string[] args)
{
SerializeObject("XmlNamespaces.xml");
}
public static void SerializeObject(string filename)
{
var mySerializer = new XmlSerializer(typeof(Container));
// Writing a file requires a TextWriter.
TextWriter myWriter = new StreamWriter(filename);
// Creates an XmlSerializerNamespaces and adds two
// prefix-namespace pairs.
var myNamespaces = new XmlSerializerNamespaces();
myNamespaces.Add("a", "http://www.UKMail.com/Services/Contracts/DataContracts");
Container container = new Container
{
Info = new CancelConsignmentRequest
{
request = new CancelConsignmentRequestInfo
{
AuthenticationToken = "token",
ConsignmentNumber = "12345",
Username = "username"
}
}
};
mySerializer.Serialize(myWriter, container, myNamespaces);
myWriter.Close();
}
}
public class Container
{
public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
}
[XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
public class CancelConsignmentRequest
{
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts")]
public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
}
public class CancelConsignmentRequestInfo
{
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 0)]
public string AuthenticationToken { get; set; }
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 1)]
public string Username { get; set; }
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 2)]
public string ConsignmentNumber { get; set; }
}
I have not been able to work out how to place the namespace definition with a prefix in one of the child nodes. Does anyone know how to do this in C# please? Thanks.
This is possible. The code below does what you are asking for.
class Program
{
static void Main(string[] args)
{
SerializeObject("XmlNamespaces.xml");
}
public static void SerializeObject(string filename)
{
var mySerializer = new XmlSerializer(typeof(Container));
// Writing a file requires a TextWriter.
TextWriter myWriter = new StreamWriter(filename);
// Creates an XmlSerializerNamespaces and adds two
// prefix-namespace pairs.
var myNamespaces = new XmlSerializerNamespaces();
//myNamespaces.Add("a", "http://www.UKMail.com/Services/Contracts/DataContracts");
Container container = new Container
{
Info = new CancelConsignmentRequest
{
request = new CancelConsignmentRequestInfo
{
AuthenticationToken = "token",
ConsignmentNumber = "12345",
Username = "username"
}
}
};
mySerializer.Serialize(myWriter, container, myNamespaces);
myWriter.Close();
}
}
public class Container
{
public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
}
public class CancelConsignmentRequest
{
public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
}
[XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
public class CancelConsignmentRequestInfo
{
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(
new[] { new XmlQualifiedName("a", "http://www.UKMail.com/Services/Contracts/DataContracts"), });
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 0)]
public string AuthenticationToken { get; set; }
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 1)]
public string Username { get; set; }
[XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 2)]
public string ConsignmentNumber { get; set; }
}

C# .net 4.6 XmlSerializerNamespaces XmlSerializer output problem

I need the following output from Pojo classes to Xml.
It's .net 4.6.1, C#.
Problem is in the namespaces and the produced prefixes.
How can I get the node:
<blablubb:Message SOAP-ENV:mustUnderstand="1" xmlns:blablubb="urn:blablubb-com:schemas:blablubb">
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<blablubb:Message SOAP-ENV:mustUnderstand="1" xmlns:blablubb="urn:blablubb-com:schemas:blablubb">
<blablubb:Type>INET_TRANS</blablubb:Type>
<blablubb:Function>RECEIVE_CUSTOMER_ORDER</blablubb:Function>
<blablubb:Sender>CONNECT</blablubb:Sender>
<blablubb:Receiver>CONNECT</blablubb:Receiver>
<blablubb:SentAt>2018-08-30T10:43:37+02:00</blablubb:SentAt>
<blablubb:ExpiresAt>2018-09-30T10:43:37+02:00</blablubb:ExpiresAt>
</blablubb:Message>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ORDERS xmlns="urn:blablubb-com:schemas:inbound_distribution_transactions_create_customer_order_request" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BUYER></BUYER>
<CONTACT_REFERENCE>OAK</CONTACT_REFERENCE>
<EAN_LOCATION_DELIVERY_ADDRESS>10901000</EAN_LOCATION_DELIVERY_ADDRESS>
<CURRENCY_CODE>EUR</CURRENCY_CODE>
<ORDER_DATE>2018-08-27T09:01:01</ORDER_DATE>
<OUR_CUSTOMER_NO>2</OUR_CUSTOMER_NO>
<SUPPLIER_ADDRESS_NO></SUPPLIER_ADDRESS_NO>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Pojos that get serialized:
SoapDocument:
[Serializable]
[XmlRoot("Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[XmlInclude(typeof(SoapHeader))]
public class SoapDocument {
[XmlElement("Header")]
public SoapHeader soapHeader { get; set; }
[XmlElement("Body",typeof(IfsOrdersXmlDocument))]
public object soapBody { get; set; }
}
SoapHeader :
[Serializable]
[XmlRoot("Header")]
[XmlInclude(typeof(SoapMessage))] // include type class IfsOrderLineXmlDocument
public class SoapHeader {
[XmlElement("Message", Namespace = "urn:blablubb-com:schemas:blablubb")]
public SoapMessage soapMessage { get; set; }
}
SoapBody :
[Serializable]
[XmlInclude(typeof(IfsXmlDocument)), XmlInclude(typeof(IfsOrdersXmlDocument))]
[SoapInclude(typeof(IfsXmlDocument)), SoapInclude(typeof(IfsOrdersXmlDocument))]
public class SoapBody {
[XmlElement("Body")]
public IfsXmlDocument soapBody { get; set; }
}
SoapMessage:
[Serializable]
//[XmlType("blablubb")]
[XmlRoot("Message", Namespace = "urn:blablubb-com:schemas:blablubb")]
public class SoapMessage {
[XmlElement("Type")]
public string Type { get; set; }
[XmlElement("Function")]
public string Function { get; set; }
[XmlElement("Sender")]
public string Sender { get; set; }
[XmlElement("Receiver")]
public string Receiver { get; set; }
[XmlElement("SentAt")]
public string SentAt { get; set; }
[XmlElement("ExpiresAt")]
public string ExpiresAt { get; set; }
}
Code that produces the Xml,
So the problem is in the namespaces and prefixes ......
XmlSerializerNamespaces ns = createSoapDocument();
XmlSerializer serializer = new XmlSerializer(typeof(HeinzApi.Soap.SoapDocument), new Type[] { typeof(IfsXmlDocument), typeof(IfsOrdersXmlDocument) });
FileStream fs = new FileStream(xmlTargetPath, FileMode.Create);
serializer.Serialize(fs, soapDocument, ns);
fs.Close();`
And this is what I get:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<Message xmlns="urn:blablubb-com:schemas:blablubb">
<Type>INET_TRANS</Type>
<Function>RECEIVE_CUSTOMER_ORDER</Function>
<Sender>CONNECT</Sender>
<Receiver>CONNECT</Receiver>
<SentAt>2018-01-03T10:43:37+02:00</SentAt>
<ExpiresAt>2018-08-02T10:43:37+02:00</ExpiresAt>
</Message>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
This is the createSoapDocument method that adds namespaces to the XmlSerializer Namespaces object:
private XmlSerializerNamespaces createSoapDocument() {
soapMessage.Type = "INET_TRANS";
soapMessage.Function = "RECEIVE_CUSTOMER_ORDER";
soapMessage.Sender = "CONNECT";
soapMessage.Receiver = "CONNECT";
soapMessage.SentAt = "2018-01-03T10:43:37+02:00";
soapMessage.ExpiresAt = "2018-08-02T10:43:37+02:00";
soapHeader.soapMessage = soapMessage;
soapDocument.soapHeader = soapHeader;
//soapDocument.soapBody = (IfsXmlDocument)targetXmlBaseDocument; ;
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
ns.Add("blablubb", "urn:blablubb-com:schemas:blablubb");
return ns;
}
Edit: This is the result after adding the namespaces to XmlSerializerNamespaces:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:blablubb="urn:blablubb-com:schemas:blablubb" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<blablubb:Message>
<blablubb:Type>INET_TRANS</blablubb:Type>
<blablubb:Function>RECEIVE_CUSTOMER_ORDER</blablubb:Function>
<blablubb:Sender>CONNECT</blablubb:Sender>
<blablubb:Receiver>CONNECT</blablubb:Receiver>
<blablubb:SentAt>2018-01-03T10:43:37+02:00</blablubb:SentAt>
<blablubb:ExpiresAt>2018-08-02T10:43:37+02:00</blablubb:ExpiresAt>
</blablubb:Message>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
You need to tell the serializer about your blahblubb namespace by adding it to your XmlSerializerNamespaces object.
ns.Add("blablubb", "urn:bla-com:schemas:blablubb");
Don't forget to change
[XmlElement("Body")]
to
[XmlElement("Body", Namespace="urn:bla-com:schemas:blablubb")]

There is an error in XML document C# Xamarin

I am getting the following error in my Xamarin Forms app but I don't know what the problem is:
System.InvalidOperationException: There is an error in XML document.
items xmlns=''> was not expected
I have a basic XML file that I have added as an embedded resource:
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<id>1</id>
<name>a name</name>
<address>an address</address>
<postcode>a postcode</postcode>
</item>
<item>
<id>2</id>
<name>name 2</name>
<address>address 2</address>
<postcode>postcode 2</postcode>
</item>
<item>
<id>3</id>
<name>name 3</name>
<address>address 3</address>
<postcode>postcode 3</postcode>
</item>
</items>
I have the following method to read the XML file:
public static List<Item> GetItemList()
{
var assembly = typeof(MyNewPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("MyNewApp.allitems.xml");
List<Item> itemsFullList;
using (var reader = new System.IO.StreamReader(stream))
{
var serializer = new XmlSerializer(typeof(List<Item>));
itemsFullList = (List<Item>)serializer.Deserialize(reader);
}
return itemsFullList;
}
I also have a standard class to represent each item:
public class Item
{
public Item()
{
}
public string name { get; set; }
public string address { get; set; }
public string postcode { get; set; }
}
I don't know why I am getting the error as from what I can see, the XML document is formatted just fine. I am using this article as a guide but I am having no luck: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/files/
Anyone know what I am doing wrong here?
Thanks.
That class structure will not deserialize to a list of Item, it will deserialize to a single object that has a property of type Item[].
You will probably want to change class and property names to make more sense, but this is how Visual Studio generates the class structure based on your xml (Edit > Paste Special)
void Main()
{
string xml = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<items>
<item>
<id>1</id>
<name>a name</name>
<address>an address</address>
<postcode>a postcode</postcode>
</item>
<item>
<id>2</id>
<name>name 2</name>
<address>address 2</address>
<postcode>postcode 2</postcode>
</item>
<item>
<id>3</id>
<name>name 3</name>
<address>address 3</address>
<postcode>postcode 3</postcode>
</item>
</items>";
using (MemoryStream ms = new MemoryStream())
{
XDocument.Parse(xml).Save(ms);
ms.Position = 0;
using (var reader = new System.IO.StreamReader(ms))
{
var serializer = new XmlSerializer(typeof(items));
var itemsFullList = (items)serializer.Deserialize(reader);
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(ElementName = "items", Namespace = "", IsNullable = false)]
public partial class items
{
private itemsItem[] itemField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("item")]
public itemsItem[] item
{
get
{
return this.itemField;
}
set
{
this.itemField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class itemsItem
{
private byte idField;
private string nameField;
private string addressField;
private string postcodeField;
/// <remarks/>
public byte id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
/// <remarks/>
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
public string address
{
get
{
return this.addressField;
}
set
{
this.addressField = value;
}
}
/// <remarks/>
public string postcode
{
get
{
return this.postcodeField;
}
set
{
this.postcodeField = value;
}
}
}

How to Deserialize XML using DataContractSerializer

I'm trying to deserialize an xml document:
<?xml version="1.0"?>
<games xmlns = "http://serialize">
<game>
<name>TEST1</name>
<code>TESTGAME1</code>
<ugn>1111111</ugn>
<bets>
<bet>5,00</bet>
</bets>
</game>
<game>
<name>TEST2</name>
<code>TESTGAME2</code>
<ugn>222222</ugn>
<bets>
<bet>0,30</bet>
<bet>0,90</bet>
</bets>
</game>
</games>
.cs class:
namespace XmlParse
{
using System.Collections.Generic;
using System.Runtime.Serialization;
[DataContract(Namespace = "http://serialize")]
public class game
{
#region Public Properties
[DataMember]
public string name { get; set; }
[DataMember]
public string code { get; set; }
[DataMember]
public long ugn { get; set; }
[DataMember]
public List<decimal> bets { get; set; }
#endregion
}
[KnownType(typeof(game))]
[DataContract(Namespace = "http://serialize")]
public class games
{
#region Public Properties
[DataMember]
public List<game> game { get; set; }
#endregion
}
}
Main:
FileStream fs = new FileStream(Path.Combine(this.path, xmlDocumentName), FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(games));
// Deserialize the data and read it from the instance.
games deserializedPerson = (games)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
deserializedPerson shows count = 0
what gives?
I figured it out. Maybe there are other implementations but this works. For the life of me I couldn't find any examples that use List inside an object. Here is a working example:
XML document to parse:
<?xml version="1.0"?>
<games xmlns = "http://serialize">
<game>
<name>TEST1</name>
<code>TESTGAME1</code>
<ugn>1111111</ugn>
<bets>
<bet>5,00</bet>
</bets>
</game>
<game>
<name>TEST2</name>
<code>TESTGAME2</code>
<ugn>222222</ugn>
<bets>
<bet>0,30</bet>
<bet>0,90</bet>
</bets>
</game>
</games>
.cs class:
namespace XmlParse
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;
[DataContract(Name = "game", Namespace = "")]
public class Game
{
[DataMember(Name = "name", Order = 0)]
public string Name { get; private set; }
[DataMember(Name = "code", Order = 1)]
public string Code { get; private set; }
[DataMember(Name = "ugn", Order = 2)]
public string Ugn { get; private set; }
[DataMember(Name = "bets", Order = 3)]
public Bets Bets { get; private set; }
}
[CollectionDataContract(Name = "bets", ItemName = "bet", Namespace = "")]
public class Bets : List<string>
{
public List<decimal> BetList
{
get
{
return ConvertAll(y => decimal.Parse(y, NumberStyles.Currency));
}
}
}
[CollectionDataContract(Name = "games", Namespace = "")]
public class Games : List<Game>
{
}
}
Read and parse xml document:
string fileName = Path.Combine(this.path, "Document.xml");
DataContractSerializer dcs = new DataContractSerializer(typeof(Games));
FileStream fs = new FileStream(fileName, FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
Games games = (Games)dcs.ReadObject(reader);
reader.Close();
fs.Close();

Categories

Resources