I'm just starting looking at REST API with HERE Maps.
I've got some experience of C# / .NET programming, but not very much with accessing REST APIs.
I have managed to successfully call the HERE Maps WebService and have retrieved the JSON data, but I'm trying to work out the best way to retrieve the specific information I need from this data.
I think I need to use Deserialisation, but this seems to require the creation of a suitable C# object to de-serialse into.
I was hoping that there is a repository somewhere where I could find these objects, rather than having to work them out from scratch, but can't find anything.
Any suggestions gratefully received.
Thanks,
Chris.
Json response:
{
"Response":{
"MetaInfo":{
"Timestamp":"2019-02-03T20:41:00.395+0000"
},
"View":[
{
"_type":"SearchResultsViewType",
"ViewId":0,
"Result":[
{
"Relevance":1.0,
"MatchLevel":"postalCode",
"MatchQuality":{
"PostalCode":1.0
},
"Location":{
"LocationId":"NT_CwZliV687TLYW4ZZKm4VNA",
"LocationType":"point",
"DisplayPosition":{
"Latitude":50.8082,
"Longitude":-0.39127
},
"NavigationPosition":[
{
"Latitude":50.8082,
"Longitude":-0.39127
}
],
"MapView":{
"TopLeft":{
"Latitude":50.82169,
"Longitude":-0.41262
},
"BottomRight":{
"Latitude":50.79471,
"Longitude":-0.36992
}
},
"Address":{
"Label":"BN11 3PQ, Worthing, England, United Kingdom",
"Country":"GBR",
"State":"England",
"County":"West Sussex",
"City":"Worthing",
"PostalCode":"BN11 3PQ",
"AdditionalData":[
{
"value":"United Kingdom",
"key":"CountryName"
},
{
"value":"England",
"key":"StateName"
},
{
"value":"West Sussex",
"key":"CountyName"
}
]
}
}
}
]
}
]
}
}
You can select JSON and paste C# classes in Visual Studio: Edit -> Paste Special -> Paste JSON as classes.
Then add NuGet package Newtonsoft.Json to solution and deserialize JSON to object, it will be looking as:
using Newtonsoft.Json;
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string json = "";//download json
Rootobject obj = JsonConvert.DeserializeObject<Rootobject>(json);
DateTime tt = obj.Response.MetaInfo.Timestamp;
}
}
public class Rootobject
{
public Response Response { get; set; }
}
public class Response
{
public Metainfo MetaInfo { get; set; }
public View[] View { get; set; }
}
public class Metainfo
{
public DateTime Timestamp { get; set; }
}
public class View
{
public string _type { get; set; }
public int ViewId { get; set; }
public Result[] Result { get; set; }
}
public class Result
{
public float Relevance { get; set; }
public string MatchLevel { get; set; }
public Matchquality MatchQuality { get; set; }
public Location Location { get; set; }
}
public class Matchquality
{
public float PostalCode { get; set; }
}
public class Location
{
public string LocationId { get; set; }
public string LocationType { get; set; }
public Displayposition DisplayPosition { get; set; }
public Navigationposition[] NavigationPosition { get; set; }
public Mapview MapView { get; set; }
public Address Address { get; set; }
}
public class Displayposition
{
public float Latitude { get; set; }
public float Longitude { get; set; }
}
public class Mapview
{
public Topleft TopLeft { get; set; }
public Bottomright BottomRight { get; set; }
}
public class Topleft
{
public float Latitude { get; set; }
public float Longitude { get; set; }
}
public class Bottomright
{
public float Latitude { get; set; }
public float Longitude { get; set; }
}
public class Address
{
public string Label { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string County { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public Additionaldata[] AdditionalData { get; set; }
}
public class Additionaldata
{
public string value { get; set; }
public string key { get; set; }
}
public class Navigationposition
{
public float Latitude { get; set; }
public float Longitude { get; set; }
}
}
Many thanks to all the comments. Your suggestions have been filed away for future reference.
In the end, because I only needed to access a couple of pieces of information, the whole converting to an object bitseemed a bit of overkill, so I got the result in XML instead, and used a couple of XML methods (GetElementsByTagName and ChildNodes) to extract the nodes I wanted.
But thanks again for your suggestions, and I'm sure I will use at least some of them in the future :)
Chris.
Related
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.
After making an api call, the example below shows what a typical response would be.
{
"code":"success",
"message":"Data retrieved for email",
"data":{
"attributes":{
"EMAIL":"example#example.net",
"NAME" : "Name",
"SURNAME" : "surname"
},
"blacklisted":1,
"email":"example#example.net",
"entered":"2014-01-15",
"listid":[8],
"message_sent":[{
"camp_id" : 2,
"event_time" : "2013-12-18"
},
{ "camp_id" : 8,
"event_time" : "2014-01-03"
},
{ "camp_id" : 11,
"event_time" : "2014-01-07"
}],
"hard_bounces":[{
"camp_id" : 11,
"event_time" : "2014-01-07"
}],
"soft_bounces":[],
"spam":[{
"camp_id" : 2,
"event_time" : "2014-01-09"
}],
"unsubscription":{
"user_unsubscribe":[
{
"event_time":"2014-02-06",
"camp_id":2,
"ip":"1.2.3.4"
},
{
"event_time":"2014-03-06",
"camp_id":8,
"ip":"1.2.3.4"
}
],
"admin_unsubscribe":[
{
"event_time":"2014-04-06",
"ip":"5.6.7.8"
},
{
"event_time":"2014-04-16",
"ip":"5.6.7.8"
}
]
},
"opened":[{
"camp_id" : 8,
"event_time" : "2014-01-03",
"ip" : "1.2.3.4"
}],
"clicks":[],
"transactional_attributes":[
{
"ORDER_DATE":"2015-07-01",
"ORDER_PRICE":100000,
"ORDER_ID":"1"
},
{
"ORDER_DATE":"2015-07-05",
"ORDER_PRICE":500000,
"ORDER_ID":"2"
}
],
"blacklisted_sms":1
}
}
What I need to do is to be able to read / find and attribute name and its corresponding value. I also need to know the value of blacklisted.
I don't know how to interpret the output given to easily find and read attributes and their values and also get the value of blacklisted.
Maybe if I can get it into an array, I can cycle through the array to find the value pair I am looking for? Or maybe I am overthinking it and their is an easier way.
Please note: This example only shows 3 attribute:value pairs. other calls may output more than three attribute:value pairs.
The simplest way is: You are getting the response in the JSON format and you just need it to be seralized with the use of classes and Json.NET
public class Rootobject
{
public string code { get; set; }
public string message { get; set; }
public Data data { get; set; }
}
public class Data
{
public Attributes attributes { get; set; }
public int blacklisted { get; set; }
public string email { get; set; }
public string entered { get; set; }
public int[] listid { get; set; }
public Message_Sent[] message_sent { get; set; }
public Hard_Bounces[] hard_bounces { get; set; }
public object[] soft_bounces { get; set; }
public Spam[] spam { get; set; }
public Unsubscription unsubscription { get; set; }
public Opened[] opened { get; set; }
public object[] clicks { get; set; }
public Transactional_Attributes[] transactional_attributes { get; set; }
public int blacklisted_sms { get; set; }
}
public class Attributes
{
public string EMAIL { get; set; }
public string NAME { get; set; }
public string SURNAME { get; set; }
}
public class Unsubscription
{
public User_Unsubscribe[] user_unsubscribe { get; set; }
public Admin_Unsubscribe[] admin_unsubscribe { get; set; }
}
public class User_Unsubscribe
{
public string event_time { get; set; }
public int camp_id { get; set; }
public string ip { get; set; }
}
public class Admin_Unsubscribe
{
public string event_time { get; set; }
public string ip { get; set; }
}
public class Message_Sent
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Hard_Bounces
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Spam
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Opened
{
public int camp_id { get; set; }
public string event_time { get; set; }
public string ip { get; set; }
}
public class Transactional_Attributes
{
public string ORDER_DATE { get; set; }
public int ORDER_PRICE { get; set; }
public string ORDER_ID { get; set; }
}
Use Newtonsoft.Json library. One of the most powerful library.Parse your JSON to strongly typed C# object using json2csharp.com then just deserialize the string.
var model= JsonConvert.DeserializeObject<Classname>(result);
You'll need JSON.Net. Pasrse your JSON to strongly typed C# object using json2csharp.com then just deserialize the string using JsonConvert.Deserialize<RootObject>().
One way would be to:
a) Copy your JSON to Clipboard (CTRL+C)
b) On a Visual Studio class, click on EDIT-> Paste Special -> Paste JSON as classes. This will create the classes equivalent of your JSON for you. Your main object would be named as "Rootobject" and you can change this to whatever name you want.
c) Add System.Web.Extensions to your references
d) You can convert your JSON to class like so:
JavaScriptSerializer serializer = new JavaScriptSerializer();
Rootobject rootObject = serializer.Deserialize<Rootobject>(JsonString);
Where JsonString is your API output.
I have this specific JSON response that I am trying to deserialize without success. I am hoping someone can help me.
Here is the JSON response I get:
{
"num_locations": 1,
"locations": {
"98765": {
"street1": "123 Fake Street",
"street2": "",
"city": "Lawrence",
"state": "Kansas",
"postal_code": "66044",
"s_status": "20",
"system_state": "Off"
}
}
}
I used json2csharp http://json2csharp.com and got these recommended classes:
public class __invalid_type__98765
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
public class Locations
{
public __invalid_type__98765 __invalid_name__98765 { get; set; }
}
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
But when I try to use it in my code:
var locationResponse = JsonConvert.DeserializeObject<RootObject>(response.Content);
What I get is (Watch):
locationResponse : {RestSharpConsoleApplication.Program.RootObject} : RestSharpConsoleApplication.Program.RootObject
locations : {RestSharpConsoleApplication.Program.Locations} : RestSharpConsoleApplication.Program.Locations
__invalid_name__98765 : null : RestSharpConsoleApplication.Program.__invalid_type__98765
num_locations : 1 : int
Obviously I am not creating (json2csharp) the right classes for the DeserializeObject, and sadly I have no control over the JSON response (vendor = SimpliSafe).
It is obvious the "98765" is meant to be a value (location number) but json2csharp makes it into this __invalid_type__98765 class and this is probably why it gets null.
Any idea how should the classes look for this particular JSON to be successfully deserialized?
Thanks!
Zachs
You should be able to do this with a dictionary:
public class MyData{
[JsonProperty("locations")]
public Dictionary<string, Location> Locations {get;set;}
}
public class Location
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
Do you have a non-Express version of Visual Studio? If so, copy the JSON to clipboard and then go to the Visual Studio menu: Edit >> Paste special >> Paste JSON as classes.
Using that gives:
public class Rootobject {
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations {
public _98765 _98765 { get; set; }
}
public class _98765 {
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
That suggests your JSON structure is not quite right.
You can also specify the property name via an attribute to use to get around this:
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations
{
[JsonProperty("98765")]
public LocationInner Inner { get; set; }
}
public class LocationInner
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
...but it would really be better if the JSON were properly formatted such that the Locations was actually an array of location objects.
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);
What I want to know is that using Google places API. Basically I want to create a site like www.zomato.com
1) Can I show listing of all restaurants and their individual details with all the details in my city just like Google+ business page?
2) Is is possible to use this API with C#.net?
3) How much Google will charge for this?
If we look at the documentation for the Google Places API, we can see the format of the JSON that a request to the API returns. By using json2csharp, we can then easily generate a C# model for the response to a Google Places query.
public class Location
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Geometry
{
public Location location { get; set; }
}
public class OpeningHours
{
public bool open_now { get; set; }
public List<object> weekday_text { get; set; }
}
public class Photo
{
public int height { get; set; }
public List<string> html_attributions { get; set; }
public string photo_reference { get; set; }
public int width { get; set; }
}
public class Result
{
public Geometry geometry { get; set; }
public string icon { get; set; }
public string id { get; set; }
public string name { get; set; }
public OpeningHours opening_hours { get; set; }
public List<Photo> photos { get; set; }
public string place_id { get; set; }
public double rating { get; set; }
public string reference { get; set; }
public string scope { get; set; }
public List<string> types { get; set; }
public string vicinity { get; set; }
}
public class PlacesApiQueryResponse
{
public List<object> html_attributions { get; set; }
public List<Result> results { get; set; }
public string status { get; set; }
}
With a simple HTTP request to the Google Places API, we can then deserialize the query results using Json.NET.
using (var client = new HttpClient())
{
var response = await client.GetStringAsync(string.Format("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={0},{1}&radius=500&type=bar&key=YourAPIKey", latitude, longitude));
var result = JsonConvert.DeserializeObject<PlacesApiQueryResponse>(response);
}