API to Object (with array) in C# - c#

I'm returning data from transportapi.com & loading it into an object, but the data within the json array isn't being included.
The json returned is:
{
"atcocode": "490012745J",
"smscode": "47889",
"request_time": "2016-11-11T22:10:42+00:00",
"departures": {
"55": [
{
"mode": "bus",
"line": "55",
"line_name": "55",
"direction": "Bakers Arms",
"operator": "TFL",
"date": null,
"expected_departure_date": "2016-11-11",
"aimed_departure_time": null,
"expected_departure_time": "22:19",
"best_departure_estimate": "22:19",
"source": "Countdown instant"
}
]
}
}
Controller code:
var source = "http://transportapi.com/v3/uk/bus/stop/490012745J/live.json?api_key=[key]&app_id=[appid]";
Uri sourceUri = new Uri(source);
System.Net.Http.HttpClient sourceClient = new System.Net.Http.HttpClient();
System.Net.Http.HttpResponseMessage sourceResponse = await sourceClient.GetAsync(sourceUri);
var sourceArray = await sourceResponse.Content.ReadAsStringAsync();
var selections = JsonConvert.DeserializeObject<RootObject>(sourceArray);
Model class:
public class BusDepartures
{
public string mode { get; set; }
public string line { get; set; }
public string line_name { get; set; }
public string direction { get; set; }
public string busoperator { get; set; }
public object date { get; set; }
public string expected_departure_date { get; set; }
public object aimed_departure_time { get; set; }
public string expected_departure_time { get; set; }
public string best_departure_estimate { get; set; }
public string source { get; set; }
}
public class Departures
{
// First attempt, use BusDepartures object.
//public List<BusDepartures> BusDepartures { get; set; }
// Second attempt (as "55" is an array), use array, then convert to object later.
public string[] routes { get; set; }
}
public class RootObject
{
public string atcocode { get; set; }
public string smscode { get; set; }
public string request_time { get; set; }
public Departures departures { get; set; }
}
Within the Departures class I did try and create a BusDepartures object to store the details of the departures, but I wondered whether, as it is an array, I should use the routes array instead? However when stepping through the code, the BusDepartures object (when it was uncommented) and the routes array were both null.
Any ideas? What am I missing?
Update:
Thanks to botond.botos for the answer. I amended my class to
public class RootObject
{
public string atcocode { get; set; }
public string smscode { get; set; }
public string request_time { get; set; }
public IDictionary<int, IEnumerable<BusDepartures>> departures { get; set; }
}
and it worked.

You won't need the Departures class, and try to change the RootObject class the following way:
public class RootObject
{
public string atcocode { get; set; }
public string smscode { get; set; }
public string request_time { get; set; }
public IDictionary<int, IEnumerable<BusDepartures>> departures { get; set; }
}

I'm pretty sure your trying to map the property name "55" to a non-existent c# property. Either modify the json (which i'm assuming you can't) or use a more generic property to handle the departures.
I'm thinking maybe something like a generic Dictionary(Of int, List(of Departure)) .... which is of course vb and I'm going to guess at new Dictionary<#int, List>() in c# ? :)
public class departures {
public Dictionary<int, List<Departure>> BusDepartures {get; set; }
}

Related

How do I convert a Json response into a C# object? [duplicate]

I'm trying to deserialize JSON into a custom object but all my properties are set to null and not sure what's going on. Does anyone see anything wrong?
JSON Example
{
"Keys": [
{
"RegistrationKey": "asdfasdfa",
"ValidationStatus": "Valid",
"ValidationDescription": null,
"Properties": [
{
"Key": "Guid",
"Value": "i0asd23165323sdfs68661358"
}
]
}
]
}
Here is my Code, where strResponseValid is the JSON above.
Keys myDeserializedObjValid = (Keys)JsonConvert.DeserializeObject(strResponseValid, typeof(Keys));
validationStatusValid = myDeserializedObjValid.ValidationStatus;
Here are my classes
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}
check if the destination type has internal (or private) set modifier for those properties, even if the property has public access modifier itself.
public class Summary{
public Class2 Prop1 { get; internal set; }
public Class1 prop2 { get; set; }
}
Solution: remove those explicit internal access modifier and make them writable from outside
Your JSON has an outer object which contains a collection of Key objects. The following code works (I tested it):
class KeyWrapper
{
public List<Key> Keys { get; set; }
}
class Key
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> Properties { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}
public void DeserializeKeys()
{
const string json = #"{""Keys"":
[
{
""RegistrationKey"": ""asdfasdfa"",
""ValidationStatus"": ""Valid"",
""ValidationDescription"": null,
""Properties"": [
{
""Key"": ""Guid"",
""Value"": ""i0asd23165323sdfs68661358""
}
]
}
]
}";
var keysWrapper = Newtonsoft.Json.JsonConvert.DeserializeObject<KeyWrapper>(json);
}
The problem here is that you're defining Keys as just a class, when it's actually a property.
public class Response
{
public Keys Keys { get; set; }
}
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}
JSON.NET is an opt-in serialization library. The properties in your objects require attributes in order to flag them as being included in the JSON structure.
public class Keys
{
[JsonProperty(PropertyName = "RegistrationKey")]
public string RegistrationKey { get; set; }
[JsonProperty(PropertyName = "ValidationStatus")]
public string ValidationStatus { get; set; }
[JsonProperty(PropertyName = "ValidationDescription")]
public string ValidationDescription { get; set; }
[JsonProperty(PropertyName = "Properties")]
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
[JsonProperty(PropertyName = "Key")]
public string Key { get; set; }
[JsonProperty(PropertyName = "Value")]
public string Value { get; set; }
}
You don't need to define PropertiesList as a list in the class just call the PropertiesList Class as below.
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public PropertiesList PropertiesList { get; set; }
}
public class PropertiesList
{
public string Key { get; set; }
public string Value { get; set; }
}
Then try using the following to deserialize:
keys myDeserializedObjValid = JsonConvert.DeserializeObject<keys>(strResponseValid);

C# Parsing JSON String

I have tried countless methods to Parse my JSON string (Steam Public Data), yet nothing seems to work. I just want to be able to extract values from the string. For Example, obtaining the value of personaname which would return SlothGod. I have JSON.NET installed in my project.
Here is my JSON:
{
"response": {
"players": [
{
"steamid": "76561198301407459",
"communityvisibilitystate": 3,
"profilestate": 1,
"personaname": "SlothGod",
"lastlogoff": 1508389707,
"commentpermission": 1,
"profileurl": "http://steamcommunity.com/id/sleuthgud/",
"avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba.jpg",
"avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_medium.jpg",
"avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_full.jpg",
"personastate": 0,
"realname": "Josh",
"primaryclanid": "103582791460168790",
"timecreated": 1462086929,
"personastateflags": 0,
"loccountrycode": "AU",
"locstatecode": "QLD"
}
]
}
}
Main method suggested to me:
public class Details
{
public string personaname { get; set; }
}
private void GetSteamDetails()
{
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Details>(SteamDetailsJson);
SteamName = data.personaname;
}
This is placed before Page_Load(). I then call GetSteamDetails(); when I want to fetch the name.
After my question being down voted, I decided to not give up on this problem. After extensive research, trial and error, and YouTube tutorials which are the most helpful IMO. I found that the data was containing a JSON array, and yes I will admit, I was confused with this, but the answer was to simply treat it like a C# array and add [1] to the end of players.
Details details = new Details();
public class Details
{
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public string realname { get; set; }
public string personaname { get; set; }
public string steamid { get; set; }
}
private void GetSteamDetails()
{
var SteamDetails= JsonConvert.DeserializeObject<dynamic>(SteamDetailsJson);
avatar = SteamDetails.response.players[1].avatar.ToString();
personaname = SteamDetails.response.players[1].personaname.ToString();
}
Based on the JSON string you provided, you should have the following C# classes to support it, or to deserialize the JSON object values into: I used this link to generate the classes.
public class Player
{
public string steamid { get; set; }
public int communityvisibilitystate { get; set; }
public int profilestate { get; set; }
public string personaname { get; set; }
public int lastlogoff { get; set; }
public int commentpermission { get; set; }
public string profileurl { get; set; }
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public int personastate { get; set; }
public string realname { get; set; }
public string primaryclanid { get; set; }
public int timecreated { get; set; }
public int personastateflags { get; set; }
public string loccountrycode { get; set; }
public string locstatecode { get; set; }
}
public class Response
{
public List<Player> players { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}
Then, using Newtonsoft.Json, you can deserialize the JSON object into your C# classes as follow:
JsonConvert.DeserializeObject<RootObject>("yourJsonString");
You mention that Newtonsoft.Json already referenced in the project.
Use class to represent json data structure, then you can easy deserialize it.
You can use only properties you need in the class.
public class Player
{
public string personaname { get; set; }
}
var player = Newtonsoft.Json.JsonConvert.DeserializeObject<Player>(jsonString);
// use player.personaname
For updates question create classes which represent your data structure
public class Team
{
public List<Player> players { get; set; }
}
public class Response
{
public Team response { get; set; }
}
You can use http://json2csharp.com/ to generate a class automatically from a JSON string.

Sending Json Arrays within Object to API

i need to POST arrays within object to api that will looks like this:
{
"ds_seatInfo": [
{
"SEAT_LOC_NO": "00201901",
"SEAT_LOC_NO": "00201902"
}
],
"SCN_SCH_SEQ": "13178",
"REQ_FG_CD": "01",
"LOCK_APRV_KEY": "123123"
}
i was tried using Models that define as follow:
public class ds_seatInfo
{
public List<string> SEAT_LOC_NO { get; set; }
}
public class BookParam
{
public string SCN_SCH_SEQ { get; set; }
public ds_seatInfo ds_seatInfo { get; set; }
public string REQ_FG_CD { get; set; }
public string LOCK_APRV_KEY { get; set; }
}
but the result aren't as expected, that's model return:
"{\"SCN_SCH_SEQ\":\"13178\",\"ds_seatInfo\":{\"SEAT_LOC_NO\":[\"00201901\",\"00201902\"]},\"REQ_FG_CD\":\"01\",\"LOCK_APRV_KEY\":\"123123\"}"
which means the SEAT_LOC_NO doesn't read as expected. i am using Newtonsoft for Serialize the Model.
What should i do?
Haven't tested it, but may be this will help you or get you in the right direction:
public class BookParam
{
[JsonProperty("ds_seatInfo")]
public List<KeyValuePair<string, string>> SetInfos = new List<KeyValuePair<string, string>>();
[JsonProperty("SCN_SCH_SEQ")]
public string ScnSchSeq { get; set; }
[JsonProperty("REQ_FG_CD")]
public string ReqFgCd { get; set; }
[JsonProperty("LOCK_APRV_KEY")]
public string LockAprvKey { get; set; }
}
And when you add items to SetInfos try like this:
SetInfos.Add(new KeyValuePair<string, string>("SEAT_LOC_NO", "00201901"));
Edit
Another possible implementation
public class BookParam
{
[JsonProperty("ds_seatInfo")]
public List<SeatInfo> DsSeatInfo = new List<SeatInfo>();
[JsonProperty("SCN_SCH_SEQ")]
public string ScnSchSeq { get; set; }
[JsonProperty("REQ_FG_CD")]
public string ReqFgCd { get; set; }
[JsonProperty("LOCK_APRV_KEY")]
public string LockAprvKey { get; set; }
}
public class SeatInfo()
{
[JsonProperty("SEAT_LOC_NO")]
public string SeatLocNo { get; set; }
}

Unable to deserialize JSON in c#

I am getting the below JSON in response from a REST API.
{
"data":{
"id":123,
"zoneid":"mydomain.com",
"parent_id":null,
"name":"jaz",
"content":"172.1 6.15.235",
"ttl":60,
"priority":null,
"type":"A",
"regions":[
"global"
],
"system_record":false,
"created_at":"2017-09-28T12:12:17Z",
"updated_at":"2017-09-28T12:12:17Z"
}
}
and trying to resolve using below code but that doesn't result in a correctly deserialized type.
var model = JsonConvert.DeserializeObject<ResponseModel>(response);
below is a class according the field I received in JSON response.
public class ResponseModel
{
public int id { get; set; }
public string zone_id { get; set; }
public int parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public int priority { get; set; }
public string type { get; set; }
public string[] regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
What is missing?
You're missing a wrapper class.
public class Wrapper
{
public ResponseModel data {get;set}
}
and then do:
var model = JsonConvert.DeserializeObject<Wrapper>(response).data;
to get the instance of your ResponseModel out the data property.
You can deduct this from your json:
{ "data":
{ "id":123, /*rest omitted */ }
}
The type that will receive this JSON needs to have a property named data. The suggested Wrapper class acts as that type.
According to json2csharp website, your model seems to be incorrect. Try this one :
public class ResponseModel
{
public int id { get; set; }
public string zoneid { get; set; }
public object parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public object priority { get; set; }
public string type { get; set; }
public List<string> regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
public class RootObject
{
public ResponseModel data { get; set; }
}
Here a cool trick you can do in Visual Studio 2015-2017 where it generates the the correct class if you just copy the JSON (ctrl + c).
You need to create a new class in visual studio and once inside the class go to Edit menu -> Paste special -> paste JSON As Classes.
Steps to generate json class
This will generate the C# object for that json for you and save you all the hassle :)
Your model does not match your response - it matches the data property. Simply wrap another object round it
public class ResponseData
{
public ResponseModel Data {get; set; {
}
and then
var model = JsonConvert.DeserializeObject<ResponseData>(response);

Access Elements in JSON File Using C#

I have an JSON result like this
{
"authenticationResultCode":"ValidCredentials",
"brandLogoUri":"http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png",
"copyright":"Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
"resourceSets":[
{
"estimatedTotal":1,
"resources":[
{
"__type":"Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1",
"bbox":[
47.636257744012461,
-122.13735364288299,
47.643983179153814,
-122.12206713944467
],
"name":"1 Microsoft Way, Redmond, WA 98052",
"point":{
"type":"Point",
"coordinates":[
47.640120461583138,
-122.12971039116383
]
},
"address":{
"addressLine":"1 Microsoft Way",
"adminDistrict":"WA",
"adminDistrict2":"King Co.",
"countryRegion":"United States",
"formattedAddress":"1 Microsoft Way, Redmond, WA 98052",
"locality":"Redmond",
"postalCode":"98052"
},
"confidence":"High",
"entityType":"Address",
"geocodePoints":[
{
"type":"Point",
"coordinates":[
47.640120461583138,
-122.12971039116383
],
"calculationMethod":"InterpolationOffset",
"usageTypes":[
"Display"
]
},
{
"type":"Point",
"coordinates":[
47.640144601464272,
-122.12976671755314
],
"calculationMethod":"Interpolation",
"usageTypes":[
"Route"
]
}
],
"matchCodes":[
"Good"
]
}
]
}
],
"statusCode":200,
"statusDescription":"OK",
"traceId":"b0b1286504404eafa7e7dad3e749d570"
}
I want to get a list of objects, and every object will contain the value of coordinates
So how can access these element by name?
I am using C# as a code behind.
You can use package like Json.NET for this task.
and easily you can generate classes by giving json string from http://json2csharp.com/
then you can access properties of items as below
RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonText);
below are the classes generated from the json2csharp for given json
public class Point
{
public string type { get; set; }
public List<double> coordinates { get; set; }
}
public class Address
{
public string addressLine { get; set; }
public string adminDistrict { get; set; }
public string adminDistrict2 { get; set; }
public string countryRegion { get; set; }
public string formattedAddress { get; set; }
public string locality { get; set; }
public string postalCode { get; set; }
}
public class GeocodePoint
{
public string type { get; set; }
public List<double> coordinates { get; set; }
public string calculationMethod { get; set; }
public List<string> usageTypes { get; set; }
}
public class Resource
{
public string __type { get; set; }
public List<double> bbox { get; set; }
public string name { get; set; }
public Point point { get; set; }
public Address address { get; set; }
public string confidence { get; set; }
public string entityType { get; set; }
public List<GeocodePoint> geocodePoints { get; set; }
public List<string> matchCodes { get; set; }
}
public class ResourceSet
{
public int estimatedTotal { get; set; }
public List<Resource> resources { get; set; }
}
public class RootObject
{
public string authenticationResultCode { get; set; }
public string brandLogoUri { get; set; }
public string copyright { get; set; }
public List<ResourceSet> resourceSets { get; set; }
public int statusCode { get; set; }
public string statusDescription { get; set; }
public string traceId { get; set; }
}
Since you already appear to be using DataContractJsonSerializer, let's stick with that. The best way to deserialize json is to first define a model which will capture the relevant data e.g.
public class JsonModel
{
public int StatusCode { get; set; }
public string StatusDescription { get; set; }
public string TraceId { get; set; }
...
}
Next, decorate the model so it's fit for deserialization
[DataContract]
public class JsonModel
{
[DataMember(Name = "statusCode")]
public int StatusCode { get; set; }
[DataMember(Name = "statusDescription")]
public string StatusDescription { get; set; }
[DataMember(Name = "traceId")]
public string TraceId { get; set; }
...
}
Then finally, perform the deserialization
using (var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonData)))
{
var serializer = new DataContractJsonSerializer(typeof(JsonModel));
var model = (JsonModel) serializer.ReadObject(memoryStream);
Console.WriteLine(model.StatusCode);
}
So how can access these element by name?
The other option for deserialization which would give you the ability to reference the properties by name would be to use a dynamic object e.g.
var model = new JavaScriptSerializer().Deserialize<dynamic>(jsonData);
Console.WriteLine(model["statusCode"]);
Add the classes for all Bing Maps REST Services from the URL below to your project:
JSON Data Contracts
Then, make sure that you add the using directive:
using BingMapsRESTService.Common.JSON;
and read the string as follows (where stream is a stream for your json):
var d = new DataContractJsonSerializer(typeof(Response));
var o = d.ReadObject(stream);

Categories