I am making a web API for a application. Except for all that I had made to the web API, I want to make an HTTP POST request to a link that will send me a response in XML. I had to send a request every 5 minutes in order to take the last values of the products. These values of the XML I want to put it in a database I order to have access to it. The database I will use is MySql and I make the API in C#. I had made the model of the XML through the http://xmltocsharp.azurewebsites.net/:
[XmlRoot(ElementName = "dd")]
public class Dd
{
[XmlElement(ElementName = "code")]
public string Code { get; set; }
[XmlElement(ElementName = "dd_descr")]
public string Dd_descr { get; set; }
[XmlElement(ElementName = "dimos_descr")]
public string Dimos_descr { get; set; }
[XmlElement(ElementName = "nomos_descr")]
public string Nomos_descr { get; set; }
}
[XmlRoot(ElementName = "address")]
public class Address
{
[XmlElement(ElementName = "fulladdress")]
public string Fulladdress { get; set; }
[XmlElement(ElementName = "zipcode")]
public string Zipcode { get; set; }
[XmlElement(ElementName = "dd")]
public Dd Dd { get; set; }
}
[XmlRoot(ElementName = "product")]
public class Product
{
[XmlElement(ElementName = "code")]
public string Code { get; set; }
[XmlElement(ElementName = "description")]
public string Description { get; set; }
}
[XmlRoot(ElementName = "company")]
public class Company
{
[XmlElement(ElementName = "code")]
public string Code { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "priceentry")]
public class Priceentry
{
[XmlElement(ElementName = "station")]
public string Station { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "address")]
public Address Address { get; set; }
[XmlElement(ElementName = "product")]
public Product Product { get; set; }
[XmlElement(ElementName = "price")]
public string Price { get; set; }
[XmlElement(ElementName = "timestamp")]
public string Timestamp { get; set; }
[XmlElement(ElementName = "company")]
public Company Company { get; set; }
}
[XmlRoot(ElementName = "pricelist")]
public class Pricelist
{
[XmlElement(ElementName = "priceentry")]
public List<Priceentry> Priceentry { get; set; }
}
}
A part of the xml is:
<pricelist>
<priceentry>
<station>2</station>
<name> name </name>
<address>
<fulladdress> name </fulladdress>
<zipcode>10442</zipcode>
<dd>
<code>A1010400</code>
<dd_descr> name
</dd_descr>
<dimos_descr> name </dimos_descr>
<nomos_descr> name </nomos_descr>
</dd>
</address>
<product>
<code>11</code>
<description> name </description>
</product>
<price>1.558</price>
<timestamp>1576649282267</timestamp>
<company>
<code>2</code>
<name> name </name>
</company>
</priceentry>
What I am asking is the following: what is the best way to accomplish what I have described
Related
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; }
}
I am retrieving xml data from an web api and deserializing the data into objects.:
<Result>
<VendorInfo xml:lang="xx">
<Vendor vname="A" cpe="B">
<Product pname="C" cpe="D"/>
</Vendor>
<Vendor vname="E" cpe="F">
<Product pname="G" cpe="H"/>
</Vendor>
<Vendor vname="I" cpe="J">
<Product pname="K" cpe="L"/>
<Product pname="M" cpe="N"/>
</Vendor>
</VendorInfo>
<Status keyword="hoge" feed="bar"/>
</Result>
My current code is this:
[XmlRoot(ElementName = "Product")]
public class Product
{
[XmlAttribute(AttributeName = "pname")]
public string Pname { get; set; }
[XmlAttribute(AttributeName = "cpe")]
public string Cpe { get; set; }
}
[XmlRoot(ElementName = "Vendor")]
public class Vendor
{
[XmlArrayItem(ElementName = "Product")]
public List<Product> Product { get; set; }
[XmlAttribute(AttributeName = "vname")]
public string Vname { get; set; }
[XmlAttribute(AttributeName = "cpe")]
public string Cpe { get; set; }
}
[XmlRoot(ElementName = "VendorInfo")]
public class VendorInfo
{
[XmlElement(ElementName = "Vendor")]
public List<Vendor> Vendor { get; set; }
[XmlAttribute(AttributeName = "lang")]
public string Lang { get; set; }
}
[XmlRoot(ElementName = "Status")]
public class Status
{
[XmlAttribute(AttributeName = "feed")]
public string Feed { get; set; }
[XmlAttribute(AttributeName = "keyword")]
public string Keyword { get; set; }
}
[XmlRoot(ElementName = "Result")]
public class Result
{
[XmlElement(ElementName = "VendorInfo")]
public VendorInfo VendorInfo { get; set; }
[XmlElement(ElementName = "Status")]
public Status Status { get; set; }
}
But, This code does not working correctly.
Only first 2 Vendor elements are deserialized, Product element is not deserialized.
What am i doing wrong?
best regards
You have few things to be taken care.
Make only one element XmlRoot. Refer below link and search for "Controlling Serialization of Classes Using XmlRootAttribute and XmlTypeAttribute".
https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes
Here in your case, the "Result" class is root.
Make rest all XmlType.
In the vendor class instead of "XmlArrayItem", make it just "XmlElement".
Here is the working code.
[XmlType("Product")]
public class Product
{
[XmlAttribute(AttributeName = "pname")]
public string Pname { get; set; }
[XmlAttribute(AttributeName = "cpe")]
public string Cpe { get; set; }
}
[XmlType("Vendor")]
public class Vendor
{
[XmlElement(ElementName = "Product")]
public List<Product> Product { get; set; }
[XmlAttribute(AttributeName = "vname")]
public string Vname { get; set; }
[XmlAttribute(AttributeName = "cpe")]
public string Cpe { get; set; }
}
[XmlType("VendorInfo")]
public class VendorInfo
{
[XmlElement(ElementName = "Vendor")]
public List<Vendor> Vendor { get; set; }
[XmlAttribute(AttributeName = "xml:lang")]
public string Lang { get; set; }
}
[XmlType("Status")]
public class Status
{
[XmlAttribute(AttributeName = "feed")]
public string Feed { get; set; }
[XmlAttribute(AttributeName = "keyword")]
public string Keyword { get; set; }
}
[XmlRoot(ElementName = "Result")]
public class Result
{
[XmlElement(ElementName = "VendorInfo")]
public VendorInfo VendorInfo { get; set; }
[XmlElement(ElementName = "Status")]
public Status Status { get; set; }
}
I have an XML string resposne that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Response ResponseReference="REF_D_026_145-2601465218898798">
<ResponseDetails Language="en">
<SearchHotelPriceResponse>
<HotelDetails>
<Hotel HasExtraInfo="true" HasMap="true" HasPictures="true">
<City Code="LON">
<![CDATA[London]]>
</City>
<Item Code="IBI3">
<![CDATA[IBIS EXCEL]]>
</Item>
<LocationDetails>
<Location Code="G9">
<![CDATA[Outside Centre]]>
</Location>
<Location Code="01">
<![CDATA[Docklands]]>
</Location>
</LocationDetails>
<StarRating>3</StarRating>
<HotelRooms>
<HotelRoom Code="DB" NumberOfRooms="1"/>
</HotelRooms>
<RoomCategories>
<RoomCategory Id="001:IBI3:17082:S16700:22530:91760">
<Description>
<![CDATA[Standard Twin]]>
</Description>
<ItemPrice CommissionPercentage="0.00" Currency="USD">1870.00</ItemPrice>
<Confirmation Code="IM">
<![CDATA[AVAILABLE]]>
</Confirmation>
<Meals>
<Basis Code="B">
<![CDATA[Breakfast]]>
</Basis>
<Breakfast Code="F">
<![CDATA[Full]]>
</Breakfast>
</Meals>
<HotelRoomPrices>
<HotelRoom Code="DB">
<RoomPrice Gross="1870.00"/>
<PriceRanges>
<PriceRange>
<DateRange>
<FromDate>2016-07-30</FromDate>
<ToDate>2016-08-02</ToDate>
</DateRange>
<Price Gross="467.50" Nights="4"/>
</PriceRange>
</PriceRanges>
</HotelRoom>
</HotelRoomPrices>
<ChargeConditions>
<ChargeCondition Type="cancellation">
<Condition Charge="true" ChargeAmount="1870.00" Currency="USD" FromDay="0" ToDay="0"/>
<Condition Charge="true" ChargeAmount="467.50" Currency="USD" FromDay="1" ToDay="2"/>
<Condition Charge="false" FromDay="3"/>
</ChargeCondition>
<ChargeCondition Type="amendment">
<Condition Charge="false" FromDay="0"/>
</ChargeCondition>
<PassengerNameChange Allowable="true"/>
</ChargeConditions>
</RoomCategory>
<RoomCategory Id="001:IBI3:17082:S16700:22530:91737">
<Description>
<![CDATA[Standard Triple]]>
</Description>
<ItemPrice CommissionPercentage="0.00" Currency="USD">2804.00</ItemPrice>
<Confirmation Code="IM">
<![CDATA[AVAILABLE]]>
</Confirmation>
<Meals>
<Basis Code="B">
<![CDATA[Breakfast]]>
</Basis>
<Breakfast Code="F">
<![CDATA[Full]]>
</Breakfast>
</Meals>
<HotelRoomPrices>
<HotelRoom Code="DB">
<RoomPrice Gross="2804.00"/>
<PriceRanges>
<PriceRange>
<DateRange>
<FromDate>2016-07-30</FromDate>
<ToDate>2016-08-02</ToDate>
</DateRange>
<Price Gross="701.00" Nights="4"/>
</PriceRange>
</PriceRanges>
</HotelRoom>
</HotelRoomPrices>
<ChargeConditions>
<ChargeCondition Type="cancellation">
<Condition Charge="true" ChargeAmount="2804.00" Currency="USD" FromDay="0" ToDay="0"/>
<Condition Charge="true" ChargeAmount="701.00" Currency="USD" FromDay="1" ToDay="2"/>
<Condition Charge="false" FromDay="3"/>
</ChargeCondition>
<ChargeCondition Type="amendment">
<Condition Charge="false" FromDay="0"/>
</ChargeCondition>
<PassengerNameChange Allowable="true"/>
</ChargeConditions>
</RoomCategory>
</RoomCategories>
</Hotel>
</HotelDetails>
</SearchHotelPriceResponse>
</ResponseDetails>
</Response>
And I the class I'm tring to deserialize this response to looks like this:
using System.Collections.Generic;
using System.Xml.Serialization;
namespace example
{
[XmlRoot(ElementName = "Response")]
public class GTASearchResponse
{
[XmlElement(ElementName = "Response")]
public Response response { get; set; }
}
[XmlRoot(ElementName = "City")]
public class City
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Item")]
public class Item
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Location")]
public class Location
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "LocationDetails")]
public class LocationDetails
{
[XmlElement(ElementName = "Location")]
public List<Location> Location { get; set; }
}
[XmlRoot(ElementName = "HotelRoom")]
public class HotelRoom
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlAttribute(AttributeName = "NumberOfRooms")]
public string NumberOfRooms { get; set; }
[XmlElement(ElementName = "RoomPrice")]
public RoomPrice RoomPrice { get; set; }
[XmlElement(ElementName = "PriceRanges")]
public PriceRanges PriceRanges { get; set; }
}
[XmlRoot(ElementName = "HotelRooms")]
public class HotelRooms
{
[XmlElement(ElementName = "HotelRoom")]
public HotelRoom HotelRoom { get; set; }
}
[XmlRoot(ElementName = "ItemPrice")]
public class ItemPrice
{
[XmlAttribute(AttributeName = "CommissionPercentage")]
public string CommissionPercentage { get; set; }
[XmlAttribute(AttributeName = "Currency")]
public string Currency { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Confirmation")]
public class Confirmation
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Basis")]
public class Basis
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Breakfast")]
public class Breakfast
{
[XmlAttribute(AttributeName = "Code")]
public string Code { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Meals")]
public class Meals
{
[XmlElement(ElementName = "Basis")]
public Basis Basis { get; set; }
[XmlElement(ElementName = "Breakfast")]
public Breakfast Breakfast { get; set; }
}
[XmlRoot(ElementName = "RoomPrice")]
public class RoomPrice
{
[XmlAttribute(AttributeName = "Gross")]
public string Gross { get; set; }
}
[XmlRoot(ElementName = "DateRange")]
public class DateRange
{
[XmlElement(ElementName = "FromDate")]
public string FromDate { get; set; }
[XmlElement(ElementName = "ToDate")]
public string ToDate { get; set; }
}
[XmlRoot(ElementName = "Price")]
public class Price
{
[XmlAttribute(AttributeName = "Gross")]
public string Gross { get; set; }
[XmlAttribute(AttributeName = "Nights")]
public string Nights { get; set; }
}
[XmlRoot(ElementName = "PriceRange")]
public class PriceRange
{
[XmlElement(ElementName = "DateRange")]
public DateRange DateRange { get; set; }
[XmlElement(ElementName = "Price")]
public Price Price { get; set; }
}
[XmlRoot(ElementName = "PriceRanges")]
public class PriceRanges
{
[XmlElement(ElementName = "PriceRange")]
public PriceRange PriceRange { get; set; }
}
[XmlRoot(ElementName = "HotelRoomPrices")]
public class HotelRoomPrices
{
[XmlElement(ElementName = "HotelRoom")]
public HotelRoom HotelRoom { get; set; }
}
[XmlRoot(ElementName = "Condition")]
public class Condition
{
[XmlAttribute(AttributeName = "Charge")]
public string Charge { get; set; }
[XmlAttribute(AttributeName = "ChargeAmount")]
public string ChargeAmount { get; set; }
[XmlAttribute(AttributeName = "Currency")]
public string Currency { get; set; }
[XmlAttribute(AttributeName = "FromDay")]
public string FromDay { get; set; }
[XmlAttribute(AttributeName = "ToDay")]
public string ToDay { get; set; }
}
[XmlRoot(ElementName = "ChargeCondition")]
public class ChargeCondition
{
[XmlElement(ElementName = "Condition")]
public List<Condition> Condition { get; set; }
[XmlAttribute(AttributeName = "Type")]
public string Type { get; set; }
}
[XmlRoot(ElementName = "PassengerNameChange")]
public class PassengerNameChange
{
[XmlAttribute(AttributeName = "Allowable")]
public string Allowable { get; set; }
}
[XmlRoot(ElementName = "ChargeConditions")]
public class ChargeConditions
{
[XmlElement(ElementName = "ChargeCondition")]
public List<ChargeCondition> ChargeCondition { get; set; }
[XmlElement(ElementName = "PassengerNameChange")]
public PassengerNameChange PassengerNameChange { get; set; }
}
[XmlRoot(ElementName = "RoomCategory")]
public class RoomCategory
{
[XmlElement(ElementName = "Description")]
public string Description { get; set; }
[XmlElement(ElementName = "ItemPrice")]
public ItemPrice ItemPrice { get; set; }
[XmlElement(ElementName = "Confirmation")]
public Confirmation Confirmation { get; set; }
[XmlElement(ElementName = "Meals")]
public Meals Meals { get; set; }
[XmlElement(ElementName = "HotelRoomPrices")]
public HotelRoomPrices HotelRoomPrices { get; set; }
[XmlElement(ElementName = "ChargeConditions")]
public ChargeConditions ChargeConditions { get; set; }
[XmlAttribute(AttributeName = "Id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "RoomCategories")]
public class RoomCategories
{
[XmlElement(ElementName = "RoomCategory")]
public List<RoomCategory> RoomCategory { get; set; }
}
[XmlRoot(ElementName = "Hotel")]
public class Hotel
{
[XmlElement(ElementName = "City")]
public City City { get; set; }
[XmlElement(ElementName = "Item")]
public Item Item { get; set; }
[XmlElement(ElementName = "LocationDetails")]
public LocationDetails LocationDetails { get; set; }
[XmlElement(ElementName = "StarRating")]
public string StarRating { get; set; }
[XmlElement(ElementName = "HotelRooms")]
public HotelRooms HotelRooms { get; set; }
[XmlElement(ElementName = "RoomCategories")]
public RoomCategories RoomCategories { get; set; }
[XmlAttribute(AttributeName = "HasExtraInfo")]
public string HasExtraInfo { get; set; }
[XmlAttribute(AttributeName = "HasMap")]
public string HasMap { get; set; }
[XmlAttribute(AttributeName = "HasPictures")]
public string HasPictures { get; set; }
}
[XmlRoot(ElementName = "HotelDetails")]
public class HotelDetails
{
[XmlElement(ElementName = "Hotel")]
public Hotel Hotel { get; set; }
}
[XmlRoot(ElementName = "SearchHotelPriceResponse")]
public class SearchHotelPriceResponse
{
[XmlElement(ElementName = "HotelDetails")]
public HotelDetails HotelDetails { get; set; }
}
[XmlRoot(ElementName = "ResponseDetails")]
public class ResponseDetails
{
[XmlElement(ElementName = "SearchHotelPriceResponse")]
public SearchHotelPriceResponse SearchHotelPriceResponse { get; set; }
[XmlAttribute(AttributeName = "Language")]
public string Language { get; set; }
}
[XmlRoot(ElementName = "Response")]
public class Response
{
[XmlElement(ElementName = "ResponseDetails")]
public ResponseDetails ResponseDetails { get; set; }
[XmlAttribute(AttributeName = "ResponseReference")]
public string ResponseReference { get; set; }
}
}
unfortunately when I deserialize I get a null value for a child element of the response property, visual studio looks like this when I debug:
You can see if i put a watch on the variable answer then I only get back a null Response class. Help?
From the Xml Attributes on GTASearchResponse it looks like you are expecting a schema
<response><response> ...
because there is the root and the attribute response. I think if you just deserialize your content directly to "Response" type it might work
I am working with a third party XML API, that returns XML responses. With the API, I am trying to import orders. So, two scenario could occur when I import order with this API:
Success - e.g. xml response: http://pastebin.com/ZcvvYMX6
Failure - e.g. xml response: http://pastebin.com/iVjqMKAR
What I am working on is a wrapper for this API and I have a method called ImportOrders. Within this method, I am trying to deserialize the xml to an object so that I can return a common response.
For example; I will have a common response DTO class like this:
public class ImportOrderResponse
{
bool IsError { get; set; }
string ErrorMsg { get; set; }
string Result { get; set; }
}
and the ImportOrders method will return response conditionally like this:
if (apiResult.Contains("importFailures"))
{
// todo: deserialize
return new ImportOrderResponse()
{
IsError = true,
ErrorMsg = "todo - get failureMessage"
};
}
else
{
// todo: deserialize
return new ImportOrderResponse()
{
IsError = false,
Result = "todo - haven't worked out what i need to return"
};
}
Using this site http://xmltocsharp.azurewebsites.net I've generated the classes used for deserialization like this:
ImportSuccess.cs
[XmlRoot(ElementName = "import")]
public class ImportSuccess
{
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "operation")]
public string Operation { get; set; }
[XmlAttribute(AttributeName = "entity")]
public string Entity { get; set; }
[XmlAttribute(AttributeName = "externalReference")]
public string ExternalReference { get; set; }
[XmlAttribute(AttributeName = "item")]
public string Item { get; set; }
[XmlAttribute(AttributeName = "queryTime")]
public string QueryTime { get; set; }
}
[XmlRoot(ElementName = "importSuccesses")]
public class ImportSuccesses
{
[XmlElement(ElementName = "import")]
public List<ImportSuccess> Import { get; set; }
}
[XmlRoot(ElementName = "importResult")]
public class ImportResult
{
[XmlElement(ElementName = "importSuccesses")]
public ImportSuccesses ImportSuccesses { get; set; }
[XmlElement(ElementName = "importFailures")]
public string ImportFailures { get; set; }
[XmlElement(ElementName = "importDuplicates")]
public string ImportDuplicates { get; set; }
}
ImportFailure.cs
[XmlRoot(ElementName = "import")]
public class ImportFailure
{
[XmlElement(ElementName = "failureMessage")]
public string FailureMessage { get; set; }
[XmlElement(ElementName = "failureDetail")]
public string FailureDetail { get; set; }
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "operation")]
public string Operation { get; set; }
[XmlAttribute(AttributeName = "externalReference")]
public string ExternalReference { get; set; }
[XmlAttribute(AttributeName = "queryTime")]
public string QueryTime { get; set; }
}
[XmlRoot(ElementName = "importFailures")]
public class ImportFailures
{
[XmlElement(ElementName = "import")]
public ImportFailure Import { get; set; }
}
[XmlRoot(ElementName = "importResult")]
public class ImportResult
{
[XmlElement(ElementName = "importSuccesses")]
public string ImportSuccesses { get; set; }
[XmlElement(ElementName = "importFailures")]
public ImportFailures ImportFailures { get; set; }
[XmlElement(ElementName = "importDuplicates")]
public string ImportDuplicates { get; set; }
}
But now I have a problem. Both the success & failure response contains the node importResult but has varying fields/element names.
Now I have an error because I have a duplicate ImportResult class.
How can I solve this? What is the correct way to handle this scenario?
I believe I was being silly... I was going about this with a wrong approach.
What I did was;
Call api with correct data for a success response, took the xml and created a class
call api with wrong/bad data for a failure response, took the xml and tried to create another class
After some digging around, I realised that the response structure is very close for success/failure.
So, I called the api and instead of sending one order; I sent 3 orders for 3 specific scenario. This resulted in a single XML response like this:
http://pastebin.com/sNgWAwq1
Now I have a good structure of the XML for (Success/Failure & Duplicates). Using this XML, I've generated the following class (for deserialisation purpose):
[XmlRoot(ElementName = "import")]
public class Import
{
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "operation")]
public string Operation { get; set; }
[XmlAttribute(AttributeName = "entity")]
public string Entity { get; set; }
[XmlAttribute(AttributeName = "externalReference")]
public string ExternalReference { get; set; }
[XmlAttribute(AttributeName = "item")]
public string Item { get; set; }
[XmlAttribute(AttributeName = "queryTime")]
public string QueryTime { get; set; }
[XmlElement(ElementName = "failureMessage")]
public string FailureMessage { get; set; }
[XmlElement(ElementName = "failureDetail")]
public string FailureDetail { get; set; }
[XmlElement(ElementName = "duplicateMessage")]
public string DuplicateMessage { get; set; }
[XmlElement(ElementName = "duplicateDetail")]
public string DuplicateDetail { get; set; }
}
[XmlRoot(ElementName = "importSuccesses")]
public class ImportSuccesses
{
[XmlElement(ElementName = "import")]
public List<Import> Import { get; set; }
}
[XmlRoot(ElementName = "importFailures")]
public class ImportFailures
{
[XmlElement(ElementName = "import")]
public Import Import { get; set; }
}
[XmlRoot(ElementName = "importDuplicates")]
public class ImportDuplicates
{
[XmlElement(ElementName = "import")]
public Import Import { get; set; }
}
[XmlRoot(ElementName = "importResult")]
public class OrderImportResponse
{
[XmlElement(ElementName = "importSuccesses")]
public ImportSuccesses ImportSuccesses { get; set; }
[XmlElement(ElementName = "importFailures")]
public ImportFailures ImportFailures { get; set; }
[XmlElement(ElementName = "importDuplicates")]
public ImportDuplicates ImportDuplicates { get; set; }
}
Now, this can work for me. I can call the api and deserialise the response to the OrderImportResponse class (without checking what kind of xml response it was) and it will have all three scenario responses I am looking for.