I am struggling actually with serializing my classes to the desired XML. I have problems placing the namespaces in the correct way.
here is the needed XML:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://abc.def.schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<q0:LoginScopeHeader>
<organizationName>WebService Test Account</organizationName>
</q0:LoginScopeHeader>
<q0:SessionHeader>
<sessionId>00f63ba748474ebba5a5ce0f8fdf7ac4</sessionId>
</q0:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<q0:GroupSet>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
</q0:GroupSet>
</soapenv:Body>
Actually my class representation looks like this:
[XmlRoot(ElementName = "Envelope")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "LoginScopeHeader")]
public class LoginScopeHeader
{
[XmlElement(ElementName = "organizationName")]
public string OrganizationName { get; set; }
}
[XmlRoot(ElementName = "SessionHeader")]
public class SessionHeader
{
[XmlElement(ElementName = "sessionId")]
public string SessionId { get; set; }
}
[XmlRoot(ElementName = "Header")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body")]
public class Body
{
[XmlElement(ElementName = "GroupSet")]
public GroupSet GroupSet { get; set; }
}
[XmlRoot(ElementName = "GroupSet")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup")]
public List<StaticGroup> StaticGroup { get; set; }
}
[XmlRoot(ElementName = "staticGroup")]
public class StaticGroup
{
[XmlElement(ElementName = "number")]
public string Number { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "conference")]
public string Conference { get; set; }
[XmlElement(ElementName = "activated")]
public string Activated { get; set; }
[XmlElement(ElementName = "personsCounter")]
public string PersonsCounter { get; set; }
[XmlElement(ElementName = "messageName")]
public MessageName MessageName { get; set; }
[XmlElement(ElementName = "personNumber")]
public PersonNumber PersonNumber { get; set; }
}
[XmlRoot(ElementName = "messageName")]
public class MessageName
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
[XmlRoot(ElementName = "personNumber")]
public class PersonNumber
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
And here the extension method for the serialization:
public static string XmlSerialize<T>(this T item, bool removeNamespaces = true)
{
object locker = new object();
XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
xmlns.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
lock (locker)
{
StringBuilder stringBuilder = new StringBuilder();
using (StringWriter stringWriter = new StringWriter(stringBuilder))
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
if (removeNamespaces)
{
xmlSerializer.Serialize(xmlWriter, item, xmlns);
}
else { xmlSerializer.Serialize(xmlWriter, item); }
return stringBuilder.ToString();
}
}
}
}
I have actually no clue how the get the namespaces serialized like in the above XML.
What do I miss? Any help is highly appreciated
You need to assign your serialisation attributes with the appropriate namespaces. The Envelope, Body and Header elements have the namespace http://schemas.xmlsoap.org/soap/envelope/. So your Envelope class should look like this:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
}
You have added the namespace prefixes (q0, xsi, xsd) as properties of your Envelope class, this is not necessary so you can remove them.
The other namespace involved is http://abc.def.schema which has the q0 prefix. You should assign that where needed at the top level, for example, in the Body class, it should be assigned to the GroupSet property:
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public GroupSet GroupSet { get; set; }
}
When you come to serialize, at the moment you are not telling the serializer about the q0 namespace prefix. So you need to add this in your XmlSerialize<T> extension method:
xmlns.Add("q0", "http://abc.def.schema");
Your StaticGroup element does not have a namespace defined in your example XML. So your GroupSet needs to define an empty namespace here:
[XmlRoot(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup", Namespace = "")]
public List<StaticGroup> StaticGroup { get; set; }
}
UPDATE_1:
I have added the namespaces as suggested by jdweng like so:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = http://schemas.xmlsoap.org/soap/envelope/")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "PersonSet")]
public PersonSet PersonSet { get; set; }
}
but now I get the following XML:
<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<soapenv:LoginScopeHeader>
<soapenv:organizationName>Blablabla</soapenv:organizationName>
</soapenv:LoginScopeHeader>
<soapenv:SessionHeader>
<soapenv:sessionId>654654654654654654654</soapenv:sessionId>
</soapenv:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<soapenv:PersonSet>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:number>321321321</soapenv:number>
<soapenv:name1>John</soapenv:name1>
<soapenv:name2>Doe</soapenv:name2>
<soapenv:language>DE</soapenv:language>
<soapenv:extra />
<soapenv:remarks>remarks</soapenv:remarks>
<soapenv:pin>65454</soapenv:pin>
<soapenv:onDutyManagement>false</soapenv:onDutyManagement>
<soapenv:onDutyManagementAutomaticLogoutDuration>0</soapenv:onDutyManagementAutomaticLogoutDuration>
<soapenv:onDutyManagementNotification>false</soapenv:onDutyManagementNotification>
<soapenv:contactDataManager>false</soapenv:contactDataManager>
<soapenv:contactDataManagedBy nil="1" />
<soapenv:caseManagerAccessMode>NO_ACCESS</soapenv:caseManagerAccessMode>
<soapenv:plannedPeriodsOfAbsence nil="1" />
<soapenv:groups>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:conference_moderator>false</soapenv:conference_moderator>
<soapenv:time_offset>0</soapenv:time_offset>
<soapenv:groupNumber>123456</soapenv:groupNumber>
</soapenv:elements>
</soapenv:groups>
<soapenv:devices>
<soapenv:elements>
<soapenv:callingNumberOrEmail>s_c#gmx.ch</soapenv:callingNumberOrEmail>
<soapenv:prio_working_hours>1</soapenv:prio_working_hours>
<soapenv:prio_non_working_hours>0</soapenv:prio_non_working_hours>
<soapenv:dtmfExtensionNumber />
<soapenv:deviceName>EMail Privat</soapenv:deviceName>
</soapenv:elements>
</soapenv:devices>
</soapenv:elements>
</soapenv:PersonSet>
</soapenv:Body>
</soapenv:Envelope>
Related
I have the following xml that i want to deserialize to a c# class:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.s1.com/info/" xmlns:types="http://www.s1.com/info/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<tns:SessionInfo>
<SessionId xsi:type="xsd:string">string</SessionId>
</tns:SessionInfo>
</soap:Header>
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:LoginResponse>
<Result xsi:type="xsd:boolean">boolean</Result>
</tns:LoginResponse>
</soap:Body>
</soap:Envelope>
I am using the following classes in order to deserialize the xml:
public class SessionId
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
public class SessionInfo
{
[XmlElement(ElementName = "SessionId")]
public SessionId SessionId { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public string Id { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Header
{
[XmlElement(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
public SessionInfo SessionInfo { get; set; }
}
[XmlRoot(ElementName = "Result", Namespace = "")]
public class Result
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
public class LoginResponse
{
[XmlElement(ElementName = "Result")]
public Result Result { get; set; }
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
public LoginResponse LoginResponse { get; set; }
[XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public string EncodingStyle { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "soapenc", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soapenc { get; set; }
[XmlAttribute(AttributeName = "tns", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Tns { get; set; }
[XmlAttribute(AttributeName = "types", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Types { get; set; }
[XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soap { get; set; }
[XmlText]
public string Text { get; set; }
}
The problem is that the SessionId element is not getting deserialized, I am assuming due to the namespaces mismatch. I tried using an empty string as the namespace but that doesn't work either as it doesn't get recognized during deserialization.
Any insight on the problem is very much appreciated. Thank you!
First, SessionId has the wrong namespace. It inherits this from the parent, you need to explicitly specify that it doesn't have one by setting it to an empty string.
Secondly, the xsi:type has a special meaning, you shouldn't try to deserialise this. It's used to indicate the content type of an element - in this case, string - and will be used by the serialiser. The implication is that this is one of many acceptable types. The simplest way to define this is using object.
Putting those together, this should work:
[XmlElement(ElementName = "SessionId", Namespace = "")]
public object SessionId { get; set; }
SessionId should contain a string object with value string.
I'd also note various other minor things:
You shouldn't specify all the namespace bindings (e.g. Xsd) as part of the model. This is lower level than this model and will be handled by the serialiser.
You only need XmlRoot on the root
You don't need XmlText properties where there isn't any text
You need to make a similar change to above to deserialise Result
ElementName and AttributeName will default to the name of the property, so you don't have to specify these if that's what you want
Taking that into account, this model should work:
public class SessionInfo
{
[XmlElement(Namespace = "")]
public object SessionId { get; set; }
}
public class Header
{
[XmlElement(Namespace = "http://www.s1.com/info/")]
public SessionInfo SessionInfo { get; set; }
}
public class LoginResponse
{
[XmlElement(Namespace = "")]
public object Result { get; set; }
}
public class Body
{
[XmlElement(Namespace = "http://www.s1.com/info/")]
public LoginResponse LoginResponse { get; set; }
[XmlAttribute("encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/", Form = XmlSchemaForm.Qualified)]
public string EncodingStyle { get; set; }
}
[XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement]
public Header Header { get; set; }
[XmlElement]
public Body Body { get; set; }
}
You can see a working demo here. I've made one change to the source XML - I changed the Result value from boolean to true, else you'll get an exception because boolean isn't a valid value for that type.
This is my 3 sample xml files:
<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
<Header>
<Date>2020-03-20T09:08:29Z</Date>
<Code>A101</Code>
</Header>
<Document>
<AAA>Test Data 123</AAA>
<BBB>Test Date 456</BBB>
</Document>
</ABC>
<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
<Header>
<Date>2020-03-20T09:08:29Z</Date>
<Code>A106</Code>
</Header>
<Document>
<MMM>Test Data 123</MMM>
<ZZZ>Test Data 456</ZZZ>
<CCC>Test Data 888</CCC>
</Document>
</ABC>
<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
<Header>
<Date>2020-03-20T09:08:29Z</Date>
<Code>A100</Code>
</Header>
<Document>
<QQQ>Test Data 999</QQQ>
<LLL>Test Data 000</LLL>
</Document>
</ABC>
Notice that the Header schema is the same but the schema inside Document tag are different based on the Code tag
And here are my classes. Since the Header is the same, I move the Header to another class.
namespace Model.A100
{
[XmlRoot(ElementName = "Document")]
public class Document
{
[XmlElement(ElementName = "QQQ")]
public string QQQ { get; set; }
[XmlElement(ElementName = "LLL")]
public string LLL { get; set; }
}
[XmlRoot(ElementName = "ABC")]
public class ABC
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Document")]
public Document Document { get; set; }
}
}
namespace Model.A101
{
[XmlRoot(ElementName = "Document")]
public class Document
{
[XmlElement(ElementName = "AAA")]
public string AAA { get; set; }
[XmlElement(ElementName = "BBB")]
public string BBB { get; set; }
}
[XmlRoot(ElementName = "ABC")]
public class ABC
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Document")]
public Document Document { get; set; }
}
}
namespace Model.A106
{
[XmlRoot(ElementName = "Document")]
public class Document
{
[XmlElement(ElementName = "MMM")]
public string MMM { get; set; }
[XmlElement(ElementName = "ZZZ")]
public string ZZZ { get; set; }
[XmlElement(ElementName = "CCC")]
public string CCC { get; set; }
}
[XmlRoot(ElementName = "ABC")]
public class ABC
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Document")]
public Document Document { get; set; }
}
}
namespace Model
{
[XmlRoot(ElementName = "Header")]
public class Header
{
[XmlElement(ElementName = "Date")]
public string Date { get; set; }
[XmlElement(ElementName = "Code")]
public string Code { get; set; }
}
}
To deserialize to Xml to C# object,
var serializer = new XmlSerializer(typeof(Model.Header));
using (TextReader reader = new StreamReader(new FileStream(filePath, FileMode.Open)))
{
var obj = (Model.Header)serializer.Deserialize(reader);
// do something
}
Now that I can extract out the Header, how do I do the same for the Document tag which is based on Code tag? Surely, I can't be writing if statement or switch case.
When I deserialize the XML below, from a third-party, my objects are always null.
XML
<?xml version="1.0"?>
<OrderImport xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Reply i:nil="true">
</Reply>
<ReplyStatus i:nil="true">
<DebugInfo>
</DebugInfo>
<PerformanceLogInfo>
</PerformanceLogInfo>
</ReplyStatus>
<Reply>
<OrderNumber>4063286</OrderNumber>
</Reply>
<ReplyStatus>
<Result>0</Result>
<Message>
</Message>
</ReplyStatus>
</OrderImport>
C# Class
[XmlRoot(ElementName = "OrderImport")]
public class OrderImport
{
[XmlElement(ElementName = "Reply")]
public List<Reply> Reply { get; set; }
[XmlElement(ElementName = "ReplyStatus")]
public List<ReplyStatus> ReplyStatus { get; set; }
[XmlAttribute(AttributeName = "i", Namespace = "http://www.w3.org/2000/xmlns/")]
public string I { get; set; }
}
[XmlRoot(ElementName= "Reply")]
public class Reply
{
[XmlAttribute(AttributeName = "nil", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Nil { get; set; }
[XmlElement(ElementName = "OrderNumber")]
public string OrderNumber { get; set; }
}
[XmlRoot(ElementName = "ReplyStatus")]
public class ReplyStatus
{
[XmlElement(ElementName = "DebugInfo")]
public string DebugInfo { get; set; }
[XmlElement(ElementName = "PerformanceLogInfo")]
public string PerformanceLogInfo { get; set; }
[XmlAttribute(AttributeName = "nil", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Nil { get; set; }
[XmlElement(ElementName = "Result")]
public string Result { get; set; }
[XmlElement(ElementName = "Message")]
public string Message { get; set; }
}
I believe the problem has to do with the first occurrence of the objects Reply and ReplyStatus being null.
I'm trying to deserialize like so
httpResponseMessage.Content.ReadAsAsync<OrderImport>().Result;
However, I've found that if I deserialize like this it works just fine
stringres = httpResponseMessage.Content.ReadAsStringAsync().Result;
using (var stringreader = new StringReader(stringres))
{
var result = (OrderImport)xmlSerializer.Deserialize(stringreader);
}
I Have XML file in my project
Here is it
<?xml version="1.0"?>
<catalog>
<car id="1">
<model>Scoda Fabia</model>
<year>2011</year>
<producer>Folkwagen</producer>
<price>6000</price>
<owner>Bil Johnson</owner>
<tel>+5810456455456</tel>
<mileage>670000</mileage>
<registered>USA</registered>
<image>Fabia1.JPG</image>
</car>
<car id="2">
<model>Huindai Getz</model>
<year>2008</year>
<producer>Huindai</producer>
<price>5000</price>
<owner>Dimitrious Gregorakis</owner>
<tel>+5810456445456</tel>
<mileage>120000</mileage>
<registered>USA</registered>
<image>hyundai_getz2.jpg</image>
</car>
<car id="3">
<model>Huindai i108</model>
<year>2014</year>
<producer>Huindai</producer>
<price>15000</price>
<owner>Dex Dexter</owner>
<tel>+5815556445456</tel>
<mileage>30000</mileage>
<registered>Canada</registered>
<image>hyundaii108.jpg</image>
</car>
<car id="4">
<model>Aveo</model>
<year>2000</year>
<producer>Shevrole</producer>
<price>3500</price>
<owner>Ivan Ivanov</owner>
<tel>+5815556445477</tel>
<mileage>300000</mileage>
<registered>Mexico</registered>
<image>aveo.jpg</image>
</car>
</catalog>
I created a class from it, here is code for class
[XmlRoot(ElementName = "car")]
public class Car
{
[XmlElement(ElementName = "model")]
public string Model { get; set; }
[XmlElement(ElementName = "year")]
public string Year { get; set; }
[XmlElement(ElementName = "producer")]
public string Producer { get; set; }
[XmlElement(ElementName = "price")]
public string Price { get; set; }
[XmlElement(ElementName = "owner")]
public string Owner { get; set; }
[XmlElement(ElementName = "tel")]
public string Tel { get; set; }
[XmlElement(ElementName = "mileage")]
public string Mileage { get; set; }
[XmlElement(ElementName = "registered")]
public string Registered { get; set; }
[XmlElement(ElementName = "image")]
public string Image { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "catalog")]
public class Catalog
{
[XmlElement(ElementName = "car")]
public List<Car> Car { get; set; }
}
And Created ViewModel for it, where I defined observable collection anв define a method to fill it with data from XML
public class CarViewModel
{
public ObservableCollection<List<Car>> car { get; set; }
public void LoadCars()
{
Car = new ObservableCollection<List<Car>>();
var path = #"xml\CarsDatabase.xml";
using (TextReader reader = new StreamReader(path))
{
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
return (Catalog)serializer.Deserialize(reader);
}
}
}
In method LoadCars I need to fill car observable collections with data in my file, that is inside of the project.
How I can do this correctly?
Thank's for help.
UPDATE
I try to use this method
public void LoadCars()
{
Car = new ObservableCollection<List<Car>>();
var path = #"xml\CarsDatabase.xml";
using (TextReader reader = new StreamReader(path))
{
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
return (Catalog)serializer.Deserialize(reader);
}
}
But now I have error
Severity Code Description Project File Line Suppression State
Error CS0127 Since 'CarViewModel.LoadCars()' returns void, a return keyword must not be followed by an object expression DaxxTest C:\Users\nemes\Source\Repos\daxx_test\DaxxTest\DaxxTest\ViewModels\CarViewModel.cs 25 Active
Change
public ObservableCollection<List<Car>> car { get; set; }
to
public ObservableCollection<Car> car { get; set; }
And use XmlSerializer to serialize your xml information. Check bellow code for an example:
public ObservableCollection<Car> cars { get; set; }
public void LoadCars()
{
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
StreamReader reader = new StreamReader("CarsDatabase.xml");
var catalog = (Catalog)serializer.Deserialize(reader);
cars = new ObservableCollection<Car>(catalog.Car);
reader.Close();
}
[Serializable()]
public class Car
{
[XmlElement(ElementName = "model")]
public string Model { get; set; }
[XmlElement(ElementName = "year")]
public string Year { get; set; }
[XmlElement(ElementName = "producer")]
public string Producer { get; set; }
[XmlElement(ElementName = "price")]
public string Price { get; set; }
[XmlElement(ElementName = "owner")]
public string Owner { get; set; }
[XmlElement(ElementName = "tel")]
public string Tel { get; set; }
[XmlElement(ElementName = "mileage")]
public string Mileage { get; set; }
[XmlElement(ElementName = "registered")]
public string Registered { get; set; }
[XmlElement(ElementName = "image")]
public string Image { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[Serializable()]
[XmlRootAttribute("catalog", Namespace = "", IsNullable = false)]
public class Catalog
{
[XmlElement(ElementName = "car")]
public List<Car> Car { get; set; }
}
VS2008, .NET Framework 3.5
We're utilizing the WebEx Xml API. Here's a sample Xml response from their web service that I'm trying to deserialize into .NET classes.
<?xml version="1.0" encoding="UTF-8"?>
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service" xmlns:com="http://www.webex.com/schemas/2002/06/common"
xmlns:event="http://www.webex.com/schemas/2002/06/service/event"><serv:header><serv:response><serv:result>SUCCESS</serv:result><serv:gsbStatus>PRIMARY</s
erv:gsbStatus></serv:response></serv:header>
<serv:body>
<serv:bodyContent xsi:type="event:lstsummaryEventResponse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<event:matchingRecords>
<serv:total>2</serv:total>
<serv:returned>2</serv:returned>
<serv:startFrom>1</serv:startFrom>
</event:matchingRecords>
<event:event>
<event:sessionKey>999999</event:sessionKey>
<event:sessionName>Test Event 1</event:sessionName>
<event:sessionType>129</event:sessionType>
<event:hostWebExID>SomeName</event:hostWebExID>
<event:startDate>03/28/2012 14:30:00</event:startDate>
<event:endDate>03/28/2012 14:45:00</event:endDate>
<event:timeZoneID>11</event:timeZoneID>
<event:duration>15</event:duration>
<event:description></event:description>
<event:status>NOT_INPROGRESS</event:status>
<event:panelists></event:panelists>
<event:listStatus>PUBLIC</event:listStatus>
</event:event>
</serv:bodyContent>
</serv:body>
</serv:message>
Here's the class that we're deserializing into:
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Collections.Generic;
namespace Masonite.MTier.WebEx
{
[Serializable()]
[XmlRoot("message", Namespace = "http://www.webex.com/schemas/2002/06/service")]
public class lstsummaryEventResponsexx
{
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
public lstsummaryEventResponsexx()
{
xmlns.Add("serv", "http://www.webex.com/schemas/2002/06/service");
xmlns.Add("com", "http://www.webex.com/schemas/2002/06/common");
xmlns.Add("event", "http://www.webex.com/schemas/2002/06/service/event");
}
[XmlElement(ElementName = "header")]
public Header header { get; set; }
[XmlElement(ElementName = "body")]
public Body body { get; set; }
[Serializable()]
[XmlRoot("header")]
public class Header
{
[XmlElement(ElementName = "response")]
public Response response { get; set; }
}
[Serializable()]
[XmlRoot("body")]
[XmlInclude(typeof(lstsummaryEventResponse))]
public class Body
{
[XmlElement(ElementName = "bodyContent", Form = XmlSchemaForm.Qualified)]
public BodyContent bodyContent { get; set; }
}
[Serializable()]
public class lstsummaryEventResponse
{
}
[Serializable()]
[XmlRoot("response")]
public class Response
{
[XmlElement(ElementName = "result")]
public string result { get; set; }
[XmlElement(ElementName = "reason")]
public string reason { get; set; }
[XmlElement(ElementName = "gsbStatus")]
public string gsbStatus { get; set; }
[XmlElement(ElementName = "exceptionID")]
public string exceptionID { get; set; }
}
[Serializable()]
[XmlRoot("bodyContent")]
public class BodyContent
{
[XmlElement(ElementName = "matchingRecords", Namespace = "http://www.webex.com/schemas/2002/06/service/event")]
public MatchingRecords matchingRecords { get; set; }
[XmlElement(ElementName = "event", Namespace = "http://www.webex.com/schemas/2002/06/service/event")]
public List<EventSummary> events { get; set; }
}
[Serializable()]
[XmlRoot("matchingRecords")]
public class MatchingRecords
{
[XmlElement(ElementName = "total", Namespace = "http://www.webex.com/schemas/2002/06/service")]
public int total { get; set; }
[XmlElement(ElementName = "returned", Namespace = "http://www.webex.com/schemas/2002/06/service")]
public int returned { get; set; }
[XmlElement(ElementName = "startFrom", Namespace = "http://www.webex.com/schemas/2002/06/service")]
public int startFrom { get; set; }
}
[Serializable()]
[XmlRoot("event")]
public class EventSummary
{
[XmlElement(ElementName = "sessionKey")]
public long sessionKey { get; set; }
[XmlElement(ElementName = "sessionName")]
public string sessionName { get; set; }
[XmlElement(ElementName = "sessionType")]
public int sessionType { get; set; }
[XmlElement(ElementName = "hostWebExID")]
public string hostWebExID { get; set; }
[XmlElement(ElementName = "startDate")]
public string startDate { get; set; }
[XmlElement(ElementName = "endDate")]
public string endDate { get; set; }
[XmlElement(ElementName = "timeZoneID")]
public int timeZoneID { get; set; }
[XmlElement(ElementName = "duration")]
public int duration { get; set; }
[XmlElement(ElementName = "description")]
public string description { get; set; }
[XmlElement(ElementName = "status")]
public string status { get; set; }
[XmlElement(ElementName = "panelists")]
public string panelists { get; set; }
[XmlElement(ElementName = "listStatus")]
public listingType listStatus { get; set; }
}
}
}
The error I'm receiving:
The specified type was not recognized: name='lstsummaryEventResponse', namespace='http://www.webex.com/schemas/2002/06/service/event', at <bodyContent xmlns='http://www.webex.com/schemas/2002/06/service'>
I'm not sure how to provide the type lstsummaryEventResponse for the Deserialize method. I added another serializable class to my class above using that name, but get the same error. Any thoughts?
BodyContent can have the type event:lstsummaryEventResponse - so you have to declare the corresponding class, and then decorate the declaration of BodyContent as follows:
[Serializable()]
[XmlRoot("bodyContent")]
[XmlInclude("lstsummaryEventResponse")]
public class BodyContent {
}
Having said that, creating C# class with a serialization corresponding to some arbitrary XML is pretty tricky, I am not sure it is right approach