How to extract data from a JSON array - c#

I need some guidance here, my code works ok until I try to map the front tyre width to a label!!
How do you access the JSON array code below?
Code below
public class DVLA
{
public List<DVLAVehicle> cast { get; set; }
}
public class DVLAVehicle
{
[JsonProperty(PropertyName = "make")]
public string make { get; set; }
[JsonProperty(PropertyName = "model")]
public string model { get; set; }
[JsonProperty(PropertyName = "year")]
public int year { get; set; }
[JsonProperty(PropertyName = "frontTyres")]
public frontTyres[] frontTyres { get; set; }
[JsonProperty(PropertyName = "rearTyres")]
public rearTyres[] rearTyres { get; set; }
}
public class frontTyres
{
public int width { get; set; }
public int ratio { get; set; }
public string rim { get; set; }
public string speedRating { get; set; }
public int psi { get; set; }
public int loadIndex { get; set; }
}
var v1 = JsonConvert.DeserializeObject(TyreDetails);
lblmake.Text = v1.make;
lblmodel.Text = v1.model;
lblyear.Text = v1.year.ToString();
lblwidth.Text = v1.frontTyres.Width;

Related

Newtonsoft Json Convert does not convert json string to object

I have these classes
public class ResponseEntryInfoAndTollDue
{
public int Code { get; set; }
public string Message { get; set; }
public TagEntryInfo TagEntryInfo { get; set; }
public TollMatrix TollMatrix { get; set; }
public List<TagInfoParam> TagInfoParams { get; set; }
public ResponseEntryInfoAndTollDue()
{
TagEntryInfo = new TagEntryInfo();
TollMatrix = new TollMatrix();
TagInfoParams = new List<TagInfoParam>();
}
}
public class TagEntryInfo
{
public long TrxnID { get; set; }
public string TagRFIDNumber { get; set; }
public string EntryTrxnDTime { get; set; }
public int EntryPlaza { get; set; }
public short EntryLane { get; set; }
public string EntryDirection { get; set; }
public string EntryLaneType { get; set; }
public string PostingDateTime { get; set; }
public string Action { get; set; }
}
public class TollMatrix
{
public decimal TollDue { get; set; }
public decimal TollVat { get; set; }
public decimal TollNoVat { get; set; }
public bool IsDefaulted { get; set; }
}
public class TagInfoParam
{
public DateTime? AsOfDate { get; set; }
public Decimal? AvailableBalance { get; set; }
public string TagNumber { get; set; }
public string PLateNumber { get; set; }
public Int16 HonorPlate { get; set; }
public Int16 TagStatusID { get; set; }
public string TID { get; set; }
public string EPC { get; set; }
public string AccountTypeID { get; set; }
public Int16 AccountStatusID { get; set; }
public Int16 TagClassID { get; set; }
public Int16 Status { get; set; }
}
From a webservice I get this json string:
{"Result":{"Code":0,"Message":"With entry info computed toll due","TagEntryInfo":{"TrxnID":6666750,"TagRFIDNumber":"1234567890","EntryTrxnDTime":"2021-01-16 16:40:16.560","EntryPlaza":123,"EntryLane":1,"EntryDirection":"B","EntryLaneType":"A","PostingDateTime":"2021-01-16T16:43:16.05","Action":"A"},"TollMatrix":{"TollDue":164.0000,"TollVat":17.5700,"TollNoVat":146.4300,"IsDefaulted":false},"TagInfoParams":[{"AsOfDate":"2021-01-16T17:12:04.213","AvailableBalance":537.0000,"TagNumber":"1234567890","PLateNumber":"Q123","HonorPlate":1,"TagStatusID":1,"TID":"Elfkajs98","EPC":"889080990709","AccountTypeID":"REV","AccountStatusID":1,"TagClassID":1,"Status":1}]},"Id":351,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false}
This is how I convert it:
var response = JsonConvert.DeserializeObject(ret);
I know that it doesn't get converted because this is what I get:
This is the result:
Why is this not being converted into an object?
As Fabio also mentioned that your json contains the attribute Result which is not part of your object so you can use below logic to deserialize
var jObj = JObject.Parse(json);
var responseEntryInfoAndTollDue = JsonConvert.DeserializeObject<ResponseEntryInfoAndTollDue>(jObj["Result"].ToString());
The above code first parse the Json to JObject and uses Result property to deserialize to ResponseEntryInfoAndTollDue object.
Check this fiddle - https://dotnetfiddle.net/7Pc3sJ

Access data in JSON C# Dynamic variable

I am working with processing/consuming some data from: https://ashesescalation-api-tachyon.stardock.net/v1/products/2641/leaderboards/ladder/de5bfc9a-9092-4014-b52e-89151de42646?offset=0&count=2 (which can be opened easily in Firefox to view.)
I am able to access the data in C# by doing this:
data being the json data...
dynamic players = JArray.Parse(data);
var p = players[0];
Console.Write(p.personaName);
However I am having trouble accessing the part in the JSON data: "dataInteger" for example the "totalUnitsKilled."
p.dataInteger[0].totalUnitsKilled
That "p.dataInteger[0].totalUnitsKilled" doesn't work.
How can I access that data in C#?
Thank you very much for your help.
Warren
See image in visual studio 1
See image in visual studio 2
Kinldy take a look at my comment in your question, base on that link you need to use JsonProperty to mapped the key that has special characters and manually named it based on your needs.
Anyways, you can do the following to achieved what you need.
Copy your link to http://json2csharp.com/
Copy the generated Quicktypes and paste it to your code.
Use JsonProperty to indicate attributes on your properties for the names and manually rename properties that contains invalid_name
And DeserializeObject the object.
Here is the code:
Declare the classes from the generated quicktypes.
public class DataInteger
{
[JsonProperty(PropertyName = "totalUnitsKilled ")]
public int totalUnitsKilled { get; set; }
public int totalTitansKilled { get; set; }
public int totalTimePlayed { get; set; }
[JsonProperty(PropertyName = "substrate-TotalGamesPlayed")]
public int SubstrateTotalGamesPlayed { get; set; }
[JsonProperty(PropertyName = "phC-TotalGamesPlayed")]
public int PHCTotalGamesPlayed { get; set; }
public int lastReplayVersion { get; set; }
public int replayUploadedCount { get; set; }
}
public class RootObject
{
public string personaLadderId { get; set; }
public int rank { get; set; }
public string personaId { get; set; }
public string personaName { get; set; }
public string avatarUrl { get; set; }
public string avatarUrlSmall { get; set; }
public string avatarUrlMedium { get; set; }
public string avatarUrlLarge { get; set; }
public string ladderType { get; set; }
public string ladderId { get; set; }
public string seasonId { get; set; }
public int bracketId { get; set; }
public string bracketName { get; set; }
public int rankingScore { get; set; }
public int secondaryScore { get; set; }
public int ruleTypeId { get; set; }
public int wins { get; set; }
public int losses { get; set; }
public int ties { get; set; }
public int tieStreak { get; set; }
public int winStreak { get; set; }
public int lossStreak { get; set; }
public int longestTieStreak { get; set; }
public int longestWinStreak { get; set; }
public int longestLossStreak { get; set; }
public int bracketMaxScore { get; set; }
public int bracketScore { get; set; }
public DateTime updateDate { get; set; }
public int totalMatchesPlayed { get; set; }
public DataInteger dataInteger { get; set; }
}
Call the API (Magic begins here)
var httpClient = new HttpClient();
var link = $#"https://ashesescalation-api-tachyon.stardock.net/v1/products/2641/leaderboards/ladder/de5bfc9a-9092-4014-b52e-89151de42646?offset=0&count=2";
var response = await httpClient.GetAsync(link);
var contents = await response.Content.ReadAsStringAsync();
//deserialized json result object...
dynamic json = JsonConvert.DeserializeObject(contents);
foreach (var item in json)
{
//deserialized again the item
var data = JsonConvert.DeserializeObject<RootObject>(Convert.ToString(item));
//you can now access all the properties including dataInteger.
Console.WriteLine(Convert.ToString(data.dataInteger.totalUnitsKilled));
Console.WriteLine(Convert.ToString(data.dataInteger.totalTitansKilled));
}
Update:
If you don't want to use strongly typed class you can do parsing using JArray
JArray jsonVal = JArray.Parse(contents) as JArray;
dynamic items = jsonVal;
foreach (dynamic item in items)
{
var x = item.dataInteger;
//you can access the fields inside dataInteger.
Console.WriteLine(x["totalUnitsKilled "]);
Console.WriteLine(x["phC-TotalGamesPlayed"]);
Console.WriteLine(x["substrate-TotalGamesPlayed"]);
}
Hope this will help you.
As suggested by other users, there is a space in property name "totalUnitsKilled ", if you change it to "totalUnitsKilled". Below code will work fine:-
Console.WriteLine(p.dataInteger.totalUnitsKilled);
Your JSON string is wrong.
[{"personaLadderId":"371eaf1c-4cfe-4873-af41-56e0cb9fcf91","rank":1,"personaId":"55834d01-13f3-445e-861f-0bc4769d87cc","personaName":"Amelie","avatarUrl":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg","avatarUrlSmall":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg","avatarUrlMedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_medium.jpg","avatarUrlLarge":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg","ladderType":"Ranked","ladderId":"de5bfc9a-9092-4014-b52e-89151de42646","seasonId":"fd7dd807-4ac2-40ec-8476-a4b2937f70af","bracketId":0,"bracketName":"Legendary","rankingScore":38,"secondaryScore":2054,"ruleTypeId":1,"wins":374,"losses":32,"ties":0,"tieStreak":0,"winStreak":8,"lossStreak":0,"longestTieStreak":0,"longestWinStreak":61,"longestLossStreak":3,"bracketMaxScore":0,"bracketScore":0,"updateDate":"2018-03-03T14:13:09.647Z","totalMatchesPlayed":406,"dataInteger":{"totalUnitsKilled ":92615,"totalTitansKilled":14,"totalTimePlayed":294676,"substrate-TotalGamesPlayed":127,"phC-TotalGamesPlayed":6,"lastReplayVersion":265301040,"replayUploadedCount":160}},{"personaLadderId":"f0dd3482-f057-44d6-a626-9c9389ad2583","rank":2,"personaId":"b53815ab-d753-4415-9ea6-03a4519c3222","personaName":"Rebellions","avatarUrl":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/b9/b9847c92d44896304cc2d673e1fbe7bc99af7f5b.jpg","avatarUrlSmall":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/b9/b9847c92d44896304cc2d673e1fbe7bc99af7f5b.jpg","avatarUrlMedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/b9/b9847c92d44896304cc2d673e1fbe7bc99af7f5b_medium.jpg","avatarUrlLarge":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/b9/b9847c92d44896304cc2d673e1fbe7bc99af7f5b_full.jpg","ladderType":"Ranked","ladderId":"de5bfc9a-9092-4014-b52e-89151de42646","seasonId":"fd7dd807-4ac2-40ec-8476-a4b2937f70af","bracketId":0,"bracketName":"Legendary","rankingScore":38,"secondaryScore":2049,"ruleTypeId":1,"wins":767,"losses":188,"ties":0,"tieStreak":0,"winStreak":3,"lossStreak":0,"longestTieStreak":0,"longestWinStreak":52,"longestLossStreak":6,"bracketMaxScore":0,"bracketScore":0,"updateDate":"2017-10-29T18:03:33.92Z","totalMatchesPlayed":955,"dataInteger":{"totalUnitsKilled ":293274,"totalTitansKilled":88,"totalTimePlayed":924881,"phC-TotalGamesPlayed":4,"substrate-TotalGamesPlayed":350,"lastReplayVersion":250285270,"replayUploadedCount":703}}]
There is a space in your json key name ("totalUnitsKilled ") which is ultimately converted to a variable name.
Correct your JSON key name will fix this issue. There are other keys with error as well.
You can check at http://json2csharp.com/. Wherever it is "invalid_name", key name is wrong.
public class DataInteger
{
public int __invalid_name__totalUnitsKilled { get; set; }
public int totalTitansKilled { get; set; }
public int totalTimePlayed { get; set; }
public int __invalid_name__substrate-TotalGamesPlayed { get; set; }
public int __invalid_name__phC-TotalGamesPlayed { get; set; }
public int lastReplayVersion { get; set; }
public int replayUploadedCount { get; set; }
}
public class RootObject
{
public string personaLadderId { get; set; }
public int rank { get; set; }
public string personaId { get; set; }
public string personaName { get; set; }
public string avatarUrl { get; set; }
public string avatarUrlSmall { get; set; }
public string avatarUrlMedium { get; set; }
public string avatarUrlLarge { get; set; }
public string ladderType { get; set; }
public string ladderId { get; set; }
public string seasonId { get; set; }
public int bracketId { get; set; }
public string bracketName { get; set; }
public int rankingScore { get; set; }
public int secondaryScore { get; set; }
public int ruleTypeId { get; set; }
public int wins { get; set; }
public int losses { get; set; }
public int ties { get; set; }
public int tieStreak { get; set; }
public int winStreak { get; set; }
public int lossStreak { get; set; }
public int longestTieStreak { get; set; }
public int longestWinStreak { get; set; }
public int longestLossStreak { get; set; }
public int bracketMaxScore { get; set; }
public int bracketScore { get; set; }
public DateTime updateDate { get; set; }
public int totalMatchesPlayed { get; set; }
public DataInteger dataInteger { get; set; }
}
You can use JSON.Net attributes to define C# variables related to JSON key names. Check this for more details.
Your new class should look like:
public class DataInteger
{
[JsonProperty(PropertyName = "totalUnitsKilled ")]
public int totalUnitsKilled { get; set; }
public int totalTitansKilled { get; set; }
public int totalTimePlayed { get; set; }
[JsonProperty(PropertyName = "substrate-TotalGamesPlayed")]
public int substrateTotalGamesPlayed { get; set; }
[JsonProperty(PropertyName = "phC-TotalGamesPlayed")]
public int phCTotalGamesPlayed { get; set; }
public int lastReplayVersion { get; set; }
public int replayUploadedCount { get; set; }
}

How to grab second occurring name from xml api data with C#

I'm trying to grab the high and low from this api, I am able to get the High, but can't figure out what to do to get the Low, which is the second occurring item with the name "fahrenheit", how could I do this using the same method I used for getting the High?
if (xmlForecast.Name == "fahrenheit" && i == 0)
{
i++;
xmlHigh = xmlForecast.ReadString();
}
Since you want solution using XML response, here it is:
First, you'll need to create classes which will represent XML response.
[XmlRoot("response")]
public class Response
{
[XmlElement("version")]
public string Version { get; set; }
[XmlElement("termsofService")]
public string TermsOfService { get; set; }
[XmlElement("features")]
public Features Features { get; set; }
[XmlElement("forecast")]
public Forecast Forecast { get; set; }
}
public class Features
{
[XmlElement("forecast")]
public int Forecast { get; set; }
}
public class Forecast
{
[XmlElement("txt_forecast")]
public TxtForecast TxtForecast { get; set; }
[XmlElement("simpleforecast")]
public SimpleForecast SimpleForecast { get; set; }
}
public class TxtForecast
{
[XmlElement("date")]
public string Date { get; set; }
[XmlArray("forecastdays")]
[XmlArrayItem("forecastday")]
public List<ForecastDay> ForecastDays { get; set; }
}
public class ForecastDay
{
[XmlElement("period")]
public int Period { get; set; }
[XmlElement("icon")]
public string Icon { get; set; }
[XmlElement("icon_url")]
public string IconUrl { get; set; }
[XmlElement("title")]
public string Title { get; set; }
[XmlElement("fcttext")]
public string FctText { get; set; }
[XmlElement("fcttext_metric")]
public string FctTextMetric { get; set; }
[XmlElement("pop")]
public string Pop { get; set; }
}
public class SimpleForecast
{
[XmlArray("forecastdays")]
[XmlArrayItem("forecastday")]
public List<ForecastDay2> ForecastDays { get; set; }
}
public class ForecastDay2
{
[XmlElement("date")]
public Date Date { get; set; }
[XmlElement("period")]
public int Period { get; set; }
[XmlElement("high")]
public High High { get; set; }
[XmlElement("low")]
public Low Low { get; set; }
[XmlElement("conditions")]
public string Conditions { get; set; }
[XmlElement("icon")]
public string Icon { get; set; }
[XmlElement("icon_url")]
public string IconUrl { get; set; }
[XmlElement("skyicon")]
public string SkyIcon { get; set; }
[XmlElement("pop")]
public int Pop { get; set; }
[XmlElement("qpf_allday")]
public QpfAllday QpfAllDay { get; set; }
[XmlElement("qpf_day")]
public QpfDay QpfDay { get; set; }
[XmlElement("qpf_night")]
public QpfNight QpfNight { get; set; }
[XmlElement("snow_allday")]
public SnowAllday SnowAllday { get; set; }
[XmlElement("snow_day")]
public SnowDay SnowDay { get; set; }
[XmlElement("snow_night")]
public SnowNight SnowNight { get; set; }
[XmlElement("maxwind")]
public MaxWind MaxWind { get; set; }
[XmlElement("avewind")]
public AveWind AveWind { get; set; }
[XmlElement("avehumidity")]
public int AveHumidity { get; set; }
[XmlElement("maxhumidity")]
public int MaxHumidity { get; set; }
[XmlElement("minhumidity")]
public int MinHumidity { get; set; }
}
public class Date
{
[XmlElement("epoch")]
public string Epoch { get; set; }
[XmlElement("pretty")]
public string Pretty { get; set; }
[XmlElement("day")]
public int Day { get; set; }
[XmlElement("month")]
public int Month { get; set; }
[XmlElement("year")]
public int Year { get; set; }
[XmlElement("yday")]
public int Yesterday { get; set; }
[XmlElement("hour")]
public int Hour { get; set; }
[XmlElement("min")]
public string Min { get; set; }
[XmlElement("sec")]
public int Sec { get; set; }
[XmlElement("isdst")]
public string Isdst { get; set; }
[XmlElement("monthname")]
public string MonthName { get; set; }
[XmlElement("monthname_short")]
public string MonthNameShort { get; set; }
[XmlElement("weekday_short")]
public string WeekdayShort { get; set; }
[XmlElement("weekday")]
public string Weekday { get; set; }
[XmlElement("ampm")]
public string AmPM { get; set; }
[XmlElement("tz_short")]
public string TzShort { get; set; }
[XmlElement("tz_long")]
public string TzLong { get; set; }
}
public class High
{
[XmlElement("fahrenheit")]
public string Fahrenheit { get; set; }
[XmlElement("celsius")]
public string Celsius { get; set; }
}
public class Low
{
[XmlElement("fahrenheit")]
public string Fahrenheit { get; set; }
[XmlElement("celsius")]
public string Celsius { get; set; }
}
public class QpfAllday
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class QpfDay
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class QpfNight
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class SnowAllday
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class SnowDay
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class SnowNight
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class MaxWind
{
[XmlElement("mph")]
public int Mph { get; set; }
[XmlElement("kph")]
public int Kph { get; set; }
[XmlElement("dir")]
public string Direction { get; set; }
[XmlElement("degrees")]
public int Degrees { get; set; }
}
public class AveWind
{
[XmlElement("mph")]
public int Mph { get; set; }
[XmlElement("kph")]
public int Kph { get; set; }
[XmlElement("dir")]
public string Direction { get; set; }
[XmlElement("degrees")]
public int Degrees { get; set; }
}
Secondly, you need to deserialize XML into Response
using (HttpClient client = new HttpClient())
{
using (var stream = await client.GetStreamAsync("http://api.wunderground.com/api/ea4bb7e7839782da/forecast/q/CA/San_Francisco.xml"))
{
var serializer = new XmlSerializer(typeof(Response));
var response = (Response)serializer.Deserialize(stream);
var simpleForecast = response.Forecast.SimpleForecast;
var forecastDays = simpleForecast.ForecastDays;
var latestForecastDay = forecastDays.Last();
var latestHighFahrenheit = latestForecastDay.High.Fahrenheit;
var latestLowFahrenheit = latestForecastDay.Low.Fahrenheit;
}
}
I am using XmlSerializer but you can also use DataContractSerializer which is newer. If you decide to use DataContractSerializer keep in mind that you'll need to replace XmlElement attributes with DataContract and DataMember.
Note: I've intentionally added few unnecessary steps and variable declarations, so you can see clearly what's going on here.

JSON Serializer C#

I am developing online aircraft sales system.
But I have a problem..
A URL address have:
string urlFlightSearch = "https://api.iati.com/rest/flightSearch/" + ado.iatiKod + "";
A have class "iati.cs" in codes
public class iati
{
public class flightSearch
{
public string fromAirport { get; set; }
public bool allinFromCity { get; set; }
public string toAirport { get; set; }
public string fromDate { get; set; }
public string returnDate { get; set; }
public string adult { get; set; }
public string currency { get; set; }
}
public class Leg
{
public string flightNo { get; set; }
public string aircraft { get; set; }
public string operatorCode { get; set; }
public string operatorName { get; set; }
public string departureAirport { get; set; }
public string departureTime { get; set; }
public string departureAirportName { get; set; }
public string departureCityName { get; set; }
public string arrivalAirport { get; set; }
public string arrivalTime { get; set; }
public string arrivalAirportName { get; set; }
public string arrivalCityName { get; set; }
}
public class Detail
{
public double price { get; set; }
public double serviceFee { get; set; }
public double tax { get; set; }
public int suplement { get; set; }
}
public class Fare
{
public double totalSingleAdultFare { get; set; }
public string currency { get; set; }
public string type { get; set; }
public List<string> segmentNames { get; set; }
public int freeSeatCount { get; set; }
public Detail detail { get; set; }
}
public class Flight
{
public string id { get; set; }
public string providerKey { get; set; }
public string pricingType { get; set; }
public int packageId { get; set; }
public List<Leg> legs { get; set; }
public List<Fare> fares { get; set; }
public int segmentCount { get; set; }
public int baggage { get; set; }
public int flightTimeHour { get; set; }
public int flightTimeMinute { get; set; }
public int layoverTime { get; set; }
public bool hasCip { get; set; }
public bool canBook { get; set; }
public bool canRezerve { get; set; }
public bool dayCross { get; set; }
public bool returnFlight { get; set; }
}
public class Result
{
public string searchId { get; set; }
public List<Flight> flights { get; set; }
}
public class RootObject
{
public Result result { get; set; }
}
}
And posting...
WebClient wc = new WebClient();
var serializer = new JavaScriptSerializer();
iati.flightSearch search = new iati.flightSearch()
{
fromAirport = "IST",
allinFromCity = true,
toAirport = "AYT",
fromDate = "2013-12-23",
returnDate = "2013-12-30",
adult = "1",
currency = "EUR"
};
var serializedResult = serializer.Serialize(search);
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
string result = wc.UploadString(urlFlightSearch, serializedResult);
iati.Flight flight = serializer.Deserialize<iati.Flight>(result);
But the result returned is always coming up empty.
Regards.
use Newtonsoft
JsonConvert.DeserializeObject(result);

How can I deserialize an XML response to an object when I only need a child element of the XML?

I have the following XML that I am getting back from a WebRequest:
<?xml version="1.0" encoding="UTF-8"?>
<search>
<total_items>5</total_items>
<page_size>10</page_size>
<page_count>1</page_count>
<page_number>1</page_number>
<page_items></page_items>
<first_item></first_item>
<last_item></last_item>
<search_time>0.044</search_time>
<events>
<event id="E0-001-053379749-0">
<title>Antibalas</title>
<url>http://test.com</url>
<description>stuff</description>
<start_time>2013-01-30 20:00:00</start_time>
<stop_time></stop_time>
<tz_id></tz_id>
<tz_olson_path></tz_olson_path>
<tz_country></tz_country>
<tz_city></tz_city>
<venue_id>V0-001-000189211-5</venue_id>
<venue_url>http://blah.com</venue_url>
<venue_name>Troubadour</venue_name>
<venue_display>1</venue_display>
<venue_address>9081 Santa Monica Boulevard</venue_address>
<city_name>West Hollywood</city_name>
<region_name>California</region_name>
<region_abbr>CA</region_abbr>
<postal_code>90069</postal_code>
<country_name>United States</country_name>
<country_abbr2>US</country_abbr2>
<country_abbr>USA</country_abbr>
<latitude>34.0815917</latitude>
<longitude>-118.3892462</longitude>
<geocode_type>EVDB Geocoder</geocode_type>
<all_day>0</all_day>
<recur_string></recur_string>
<calendar_count></calendar_count>
<comment_count></comment_count>
<link_count></link_count>
<going_count></going_count>
<watching_count></watching_count>
<created>2012-12-24 11:40:43</created>
<owner>evdb</owner>
<modified>2013-01-14 21:08:04</modified>
<performers>
<performer>
<id>P0-001-000000517-4</id>
<url>http://test.com</url>
<name>Antibalas</name>
<short_bio>Afro-beat / Funk / Experimental</short_bio>
<creator>jfisher</creator>
<linker>evdb</linker>
</performer>
</performers>
<image>
<url>http://s4.evcdn.com/images/small/I0-001/000/070/311-5.jpeg_/antibalas-11.jpeg</url>
<width>48</width>
<height>48</height>
<caption></caption>
<thumb>
<url>http://s4.evcdn.com/images/thumb/I0-001/000/070/311-5.jpeg_/antibalas-11.jpeg</url>
<width>48</width>
<height>48</height>
</thumb>
<small>
<url>http://s4.evcdn.com/images/small/I0-001/000/070/311-5.jpeg_/antibalas-11.jpeg</url>
<width>48</width>
<height>48</height>
</small>
<medium>
<url>http://s4.evcdn.com/images/medium/I0-001/000/070/311-5.jpeg_/antibalas-11.jpeg</url>
<width>128</width>
<height>128</height>
</medium>
</image>
<privacy>1</privacy>
<calendars></calendars>
<groups></groups>
<going></going>
</event>
</events>
</search>
I have created the following classes:
public class EventSearch
{
public int total_items { get; set; }
public int page_size { get; set; }
public int page_count { get; set; }
public int page_number { get; set; }
public int page_items { get; set; }
public string first_item { get; set; }
public string last_item { get; set; }
public string search_time { get; set; }
public List<Event> events { get; set; }
}
public class Event
{
public string id { get; set; }
public string title { get; set; }
public string url { get; set; }
public string description { get; set; }
public DateTime start_time { get; set; }
public string venue_id { get; set; }
public string venue_url { get; set; }
public string venue_name { get; set; }
public string venue_address { get; set; }
public string city_name { get; set; }
public string region_name { get; set; }
public string region_abbr { get; set; }
public string postal_code { get; set; }
public string country_name { get; set; }
public string country_abbr { get; set; }
public string country_abbr2 { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public List<Performer> performers { get; set; }
public EventImage image { get; set; }
}
public class Performer
{
public string id { get; set; }
public string url { get; set; }
public string name { get; set; }
public string short_bio { get; set; }
}
public class EventImage
{
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
public Image thumb { get; set; }
public Image small { get; set; }
public Image medium { get; set; }
}
public class Image
{
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
In the method that I am calling, I want to return a list of events. Here's what I have so far, which is giving me the error:
was not expected.
Code:
var request = WebRequest.Create(url);
var response = request.GetResponse();
if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK)
{
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader.
StreamReader reader = new StreamReader(dataStream);
XmlSerializer serializer = new XmlSerializer(typeof(EventSearch));
EventSearch deserialized = (EventSearch)serializer.Deserialize(reader);
return deserialized.events;
}
I'm not sure what to do next. Do I need to annotate my classes?
Yes, you will need to add some Attributes to your classes to map the xml elements to your objects.
This should work, However I had to change a few things, The DateTime in the Xml is in the wrong fromat so I made it a string(you can parse as needed), also page_items is an int but it is an empty element in the xml, you wont be able to deserialize this, you will have to change to a string if it has a chance of being empty.
[XmlType("search")]
public class EventSearch
{
public int total_items { get; set; }
public int page_size { get; set; }
public int page_count { get; set; }
public int page_number { get; set; }
// public int? page_items { get; set; }
public string first_item { get; set; }
public string last_item { get; set; }
public string search_time { get; set; }
public List<Event> events { get; set; }
}
[XmlType("event")]
public class Event
{
[XmlAttribute("id")]
public string id { get; set; }
public string title { get; set; }
public string url { get; set; }
public string description { get; set; }
public string start_time { get; set; }
public string venue_id { get; set; }
public string venue_url { get; set; }
public string venue_name { get; set; }
public string venue_address { get; set; }
public string city_name { get; set; }
public string region_name { get; set; }
public string region_abbr { get; set; }
public string postal_code { get; set; }
public string country_name { get; set; }
public string country_abbr { get; set; }
public string country_abbr2 { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public List<Performer> performers { get; set; }
public EventImage image { get; set; }
}
[XmlType("performer")]
public class Performer
{
public string id { get; set; }
public string url { get; set; }
public string name { get; set; }
public string short_bio { get; set; }
}
[XmlType("image")]
public class EventImage
{
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
public Image thumb { get; set; }
public Image small { get; set; }
public Image medium { get; set; }
}
[XmlType("thumb")]
public class Image
{
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
I tested directly from file using:
using (FileStream stream = new FileStream("C:\\Test.xml", FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(EventSearch));
EventSearch deserialized = (EventSearch)serializer.Deserialize(stream);
}
But your Stream from the Webresponce should work the same as the FileStream
Hope this helps :)

Categories

Resources