First time working with JSON and related, I'm trying to get distance/duration of all possible routes from this request: https://maps.googleapis.com/maps/api/directions/json?origin=41.2091585,-8.5763016&destination=41.258913,-8.636942&mode=driving&alternatives=true&avoid=tolls&language=pt-PT&key=AIzaSyDuhdvLAny3MpraXKX-bahkXZJolm7KLbE
I got the following classes using "Paste JSON as Classes" and create one Class for each of the following ones:
public class Rootobject
{
public Geocoded_Waypoints[] geocoded_waypoints { get; set; }
public Route[] routes { get; set; }
public string status { get; set; }
}
public class Route
{
public Bounds bounds { get; set; }
public string copyrights { get; set; }
public Leg[] legs { get; set; }
public Overview_Polyline overview_polyline { get; set; }
public string summary { get; set; }
public object[] warnings { get; set; }
public object[] waypoint_order { get; set; }
}
public class Leg
{
public Distance distance { get; set; }
public Duration duration { get; set; }
public string end_address { get; set; }
public End_Location end_location { get; set; }
public string start_address { get; set; }
public Start_Location start_location { get; set; }
public Step[] steps { get; set; }
public object[] traffic_speed_entry { get; set; }
public Via_Waypoint[] via_waypoint { get; set; }
}
public class Distance
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration
{
public string text { get; set; }
public int value { get; set; }
}
For the query mentioned above I have 3 different routes (aka "legs") and I want to get the distance/duration of each one.
I came up with the following but it's not working.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(query);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
if (!string.IsNullOrEmpty(result))
{
Distance t = JsonConvert.DeserializeObject<Distance>(result);
string distance1_Value = t.value;
string distance1_Text = t.text;
Duration d = JsonConvert.DeserializeObject<Duration>(result);
string duration1_Value = d.value;
string duration1_Value = d.text;
}
}
Any help?
PS: If anyone can show me how to iterate throw each "legs" that would be great.
EDIT: Forgot to mention I'm using Newtonsoft.
I found the solution a few days ago...
First, i do the same of you, but still not working for me, so i take a look deep inside the classes auto generated by this tool and notice that some classes was missing the 's' at the end of its names..
Step, where correct name 'Steps'
Leg. correct name 'Legs'
Route. correct name 'Routes'
Do you have to fix this at entire document.
After this, you can convert directly...
Take a look at correct answer: [1]: http://pastie.org/10935748#9
Related
I have a code REST API response which is json, and parsing to JObject and pulling a value from it. But i am getting the error when parsing to JObject.
Error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
Is there any other way to convert Json string to C# object.
I have the following code:
using Newtonsoft.Json;
using (HttpResponseMessage message = httpclient.GetAsync(folderIdURL).Result)
{
if(message.IsSuccessStatusCode)
{
var dataobjects = message.Content.ReadAsStringAsync();
//dataobjects = "{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/","title":"DQL query results","author":[{"name":"EMC Documentum"}],"updated":"2019-05-02T15:19:52.508+00:00","page":1,"items-per-page":100,"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)"}],"entries":[{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=0","title":"0b0111738011c114","updated":"2019-05-02T15:19:52.508+00:00","published":"2019-05-02T15:19:52.508+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositori es/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c114","object_name":"04"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}]}},{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=1","title":"0b0111738011c115","updated":"2019-05-02T15:19:52.509+00:00","published":"2019-05-02T15:19:52.509+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c115","object_name":"05"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}]}}]}"
JObject responseObj = JObject.Parse(dataobjects.ToString());
String id = (String)responseObj["entries" -->"content"-->"properties"-->"object_name"];
}
}
}
I am expecting the value from (String)responseObject["enteries"]["content"][" properties"]["object_name"]
JObjects are a pain. You could get a sample of the JSON response and paste it into a converter like json2csharp.com. It will generate a class for you which you can then use like so:
Generated Class:
public class MyClass
{
public string SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
Usage:
if (message.IsSuccessStatusCode)
{
var deserializedObject = JsonConvert.DeserializeObject<MyClass>(response.Content.ReadAsStringAsync().Result);
Console.WriteLine(deserializedObject.SomeProperty);
}
I would suggest to follow those steps:
You need to check that your json is actually a json, because an error says it is not. You can use online tools like this
If possible, avoid JObject and generate real classes. It is not that hard if you know the structure, and you can use another online tools
Modify your code to use classes
so you will have something like:
using System;
using Newtonsoft.Json;
namespace ConsoleApp11
{
class Program
{
public class Message
{
public Enteries enteries { get; set; }
}
public class Enteries
{
public Content content { get; set; }
}
public class Content
{
public Properties properties { get; set; }
}
public class Properties
{
public string object_name { get; set; }
}
static void Main(string[] args)
{
var input = "{\"enteries\":{\"content\":{ \"properties\":{ \"object_name\":\"your value string\"}}}}";
Message msg = JsonConvert.DeserializeObject<Message>(input);
Console.WriteLine(msg?.enteries?.content?.properties?.object_name ?? "no value");
Console.ReadKey();
}
}
}
I hope it helps 😊
Thank you so much for all the help and trips. Finally i am able to get the required value from JSON string.
Here is the Final code json2csharp.com
public class Author
{
public string name { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Properties
{
public string r_object_id { get; set; }
public string object_name { get; set; }
}
public class Link3
{
public string rel { get; set; }
public string href { get; set; }
}
public class Content
{
public string json_root { get; set; }
public string definition { get; set; }
public Properties properties { get; set; }
public List<Link3> links { get; set; }
}
public class Entry
{
public string id { get; set; }
public string title { get; set; }
public DateTime updated { get; set; }
public DateTime published { get; set; }
public List<Link2> links { get; set; }
public Content content { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string title { get; set; }
public List<Author> author { get; set; }
public DateTime updated { get; set; }
public int page { get; set; }
public int items_per_page { get; set; }
public List<Link> links { get; set; }
public List<Entry> entries { get; set; }
}
Using Newtonsoft.Json
First get the list of entries from the responseObj. Then loop each entries and use LINQ to JSON to get values by property name or index.
You can use Item[Object] index on JObject/JArray and then cast the returned JValue to the type you want
JObject responseObj = JObject.Parse(dataobjects.ToString());
// get JSON result objects into a list
IList<JToken> entries = responseObj ["entries"].Children().ToList();
foreach(JToken entry in entries)
{
string object_name = (string) entry["content"]["properties"]["object_name"];
}
I am trying to read a .json response. I have pasted the response here:
https://pastebin.com/0Zgg39si
Then I use the code below. When I run the code, I get the below error for:
"var deserializedTickers"
System.NullReferenceException: 'Object reference not set to an instance of an object.'
The code is the below. I am not sure what is causing this?
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
public void test()
{
//responseBody holds the .json response
String responseBody = "";
var deserializedTickers = JsonConvert.DeserializeObject<TickersRoot>(responseBody);
foreach (var ticker in deserializedTickers.Tickers)
{
var symbol2 = ticker.Value.Symbol;
}
}
public class TickersRoot { public Dictionary<string, Ticker> Tickers { get; set; } }
public class Ticker
{
public string Symbol { get; set; }
public long Timestamp { get; set; }
public DateTime Datetime { get; set; }
public double High { get; set; }
public double Low { get; set; }
public double Bid { get; set; }
public double Ask { get; set; }
public double Vwap { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double Last { get; set; }
public double BaseVolume { get; set; }
public double QuoteVolume { get; set; }
public Info Info { get; set; }
}
public class Info
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
Based on the response, your Info class should be something like this (set the datatype to match your needs):
public class Info
{
public string Buy { get; set; }
public string Sell { get; set; }
public string Open { get; set; }
public string Low { get; set; }
public string High { get; set; }
public string Last { get; set; }
public string Vol { get; set; }
}
as you don't have a property called "Tickers" on the json body, call the JsonConver.DeserializeObject method like this:
var deserializedTickers = JsonConvert.DeserializeObject<Dictionary<string, Ticker>>(responseBody);
then you can iterate the result as:
foreach (var ticker in deserializedTickers)
{
var symbol2 = ticker.Value.Symbol;
}
I had this error when one of my [Serializable] objects only had 1 constructor with a required arg. When de-serializing, the newtonsoft.json package could not create the entity from the data, since it had a required param in its constructor.
I solved it by removing the constructor and remembering to call a helper function when instantiating objects that are not loaded from a file/json.
You can either change the root json object to have a property named "tickers" that encapsulates the dictionary
{
"tickers":{
"BTC/AUD": {
...
},
...
}
}
Or deserialize the original json directly into a dictionary
var deserializedTickers = JsonConvert.DeserializeObject<Dictionary<string, Ticker>>(responseBody);
You should also change the Info class to match the json schema
I was experiencing some to deserilize a json file until I realized the reason was that the file was formatted, prettified, beautified etc.
Using Newtonsoft.Json library and calling
JsonConvert.DeserializeObject<myObject>(mystring);
throws a JsonSerializationException:
{"Unexpected end when reading JSON. Path '', line 1, position 1."}
Then, when I repeated the operation, but with a minified, compacted, etc version of the same file it worked.
Is there a way to use this libray and deserialize data in both scenarios?
Thank you!
Your json is Valid, your model should be like this
public class Step
{
public int StepID { get; set; }
public string Description { get; set; }
public List<int> ShutMoves { get; set; }
public List<int> FeatIDs { get; set; }
public List<int> ExpSettings { get; set; }
}
public class Part
{
public int PartID { get; set; }
public string Description { get; set; }
public bool Moving { get; set; }
public List<int> FeatIDs { get; set; }
}
public class Feat
{
public int FeatID { get; set; }
public int CamID { get; set; }
public int CamFeatID { get; set; }
public int PartID { get; set; }
}
public class RootObject
{
public List<Step> Steps { get; set; }
public List<Part> Parts { get; set; }
public List<Feat> Feats { get; set; }
}
Small Example -
public void JsonDeserializeTesting() {
var testingModal = new TestingModal{Id = 1,Name = "Eminem",};
var serializeObject = JsonConvert.SerializeObject(testingModal);
var deserializeObject = JsonConvert.DeserializeObject<TestingModal>
(serializeObject);
Console.WriteLine($"{deserializeObject}");
}
public class TestingModal{
public long Id { get; set; }
public string Name { get; set; }
}
I hope this will give you abstract view of how to use Deserialize.
This was a mistake from my side. The string I was deserializing was obtained by using ReaLine(). So my code was parsing only the first line of the file.
ReadToEnd() from the stream or even File.ReadAllText fixes the issue.
Thank you for the help.
I am trying to consume a REST API via a C# Console Application and I've got as far as getting the webservice to return the JSON file, with the format:
{"status":200,"result":{"postcode":"SW1W0DT","quality":1,"eastings":528813,"northings":178953,"country":"England","nhs_ha":"London","longitude":-0.145828,"latitude":51.494853,"european_electoral_region":"London","primary_care_trust":"Westminster","region":"London","lsoa":"Westminster 023E","msoa":"Westminster 023","incode":"0DT","outcode":"SW1W","parliamentary_constituency":"Cities of London and Westminster","admin_district":"Westminster","parish":"Westminster, unparished area","admin_county":null,"admin_ward":"Warwick","ccg":"NHS Central London (Westminster)","nuts":"Westminster","codes":{"admin_district":"E09000033","admin_county":"E99999999","admin_ward":"E05000647","parish":"E43000236","parliamentary_constituency":"E14000639","ccg":"E38000031","nuts":"UKI32"}}}
I have created a class AddressInfo which is as follows:
public class AddressInfo {
public string postcode { get; set; }
public int quality { get; set; }
public int eastings { get; set; }
public int northings { get; set; }
public string country { get; set; }
public string nhs_ha { get; set; }
public string admin_county { get; set; }
public string admin_district { get; set; }
public string admin_ward { get; set; }
public double longitude { get; set; }
public double latitude { get; set; }
public string parliamentary_constituency { get; set; }
public string european_electoral_region { get; set; }
public string primary_care_trust { get; set; }
public string region { get; set; }
public string parish { get; set; }
public string lsoa { get; set; }
public string msoa { get; set; }
public string ccg { get; set; }
public string nuts { get; set; }
public object codes { get; set; }
}
The code to call the API and get the values is:
string strJSON = string.Empty;
strJSON = rClient.makeRequest();
Console.Write(strJSON);
AddressInfo AI = new AddressInfo();
AI = Newtonsoft.Json.JsonConvert.DeserializeObject<AddressInfo>(strJSON);
However, when I debug, AI is returning the values as "NULL".
Thanks
Notice that your JSON has a nested structure. The AddressInfo is contained within its result property, it isn't at the top level.
Your actual class structure to deserialize the entire JSON response should look something like this (I've called the class JsonResponse but you can name it whatever you want):
class JsonResponse{
public int status { get; set; }
public AddressInfo result { get; set; }
}
Then deserialize it like this:
JsonResponse res = JsonConvert.DeserializeObject<JsonResponse>(strJSON);
AddressInfo addressInfo = res.result;
You're missing the fact that you need an outer class that has the properties int status and AdressInfo result.
You don't need to create a separate class to deserialize the entire response, this can be done dynamically to achieve desired result:
var source = "(your JSON");
dynamic data = JObject.Parse(source);
var d = JsonConvert.SerializeObject(data.result);
AddressInfo account = JsonConvert.DeserializeObject<AddressInfo>(d);
Your JSON is nested. The result is a nested object. That's why you are experiencing this issue.
I am struggling with how to convert the following price quote JSON data into a C#
object:
{"MyFeed":
{"#Provider":"SomeProvider","MMM":
{"#name":"3M Corp","low":"194.80","high":"136.78","change":"2.80","pctchange":"0.22","ask":"135.15","bid_time":"20161104131845","bid":"134.80"}
}}
I created a C# class like so:
public class Quote
{
public string Provider { get; set; }
public Data Info { get; set; }
}
public class Data
{
public string name { get; set; }
public decimal low { get; set; }
public decimal high { get; set; }
public decimal change { get; set; }
public decimal pctchange { get; set; }
public decimal ask { get; set; }
public DateTime bid_time { get; set; }
public decimal bid { get; set; }
}
Then, in code, I am fetching the data using an HttpWebRequest, which runs just fine. But the step to deserialize the JSON data doesn't work.. It doesn't throw an error, it just has no data. That code is:
var request = HttpWebRequest.Create(new Uri("<request URL here>")) as HttpWebRequest;
request.Method = "POST";
var response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Quote quote = JsonConvert.DeserializeObject<Quote>(reader.ReadToEnd());
lblPrice.Text = string.Format("{0:c}", quote.Data.ask);
}
}
I stepped through the code, so I know the web request is working and returning a JSON string. I just don't know how to structure the C# class to accept the deserialized data. Help would be appreciated!
You should define the properties like this.
[JsonProperty(PropertyName = "#Provider")]
public string Provider { get; set; }
And
[JsonProperty(PropertyName = "#name")]
public string name { get; set; }
You have dozens other problems, like your fields are not decimal in the json, wrong class structure. Here how your class should look like:
public class MyFeed
{
[JsonProperty(PropertyName = "#Provider")]
public string Provider { get; set; }
public MMM MMM { get; set; }
}
public class RootJsonObject
{
public MyFeed MyFeed { get; set; }
}
public class MMM
{
[JsonProperty(PropertyName = "#name")]
public string name { get; set; }
public string provider { get; set; }
public string low { get; set; }
public string high { get; set; }
public string change { get; set; }
public string pctchange { get; set; }
public string ask { get; set; }
public string bid_time { get; set; }
public string bid { get; set; }
}
How you make the conversion:
RootJsonObject quote = JsonConvert.DeserializeObject<RootJsonObject>(json);
have you tried to use this json2csharp
Use JsonProperty to specify the names in the serialized string.
You need to wrap the whole Quote type in a different type as you are passing in an object that contains the object you are interested in.
You need to specify how the DateTime types are serialized.
Here is a complete and working solution with your json.
class JsonTester
{
public void Test()
{
const string json = "{\"MyFeed\":{\"#Provider\":\"SomeProvider\",\"MMM\":{\"#name\":\"3M Corp\",\"low\":\"194.80\",\"high\":\"136.78\",\"change\":\"2.80\",\"pctchange\":\"0.22\",\"ask\":\"135.15\",\"bid_time\":\"20161104131845\",\"bid\":\"134.80\"}}}";
var settings = new JsonSerializerSettings()
{
DateFormatString = "yyyyMMddHHmmss"
};
var quoteWrapper = JsonConvert.DeserializeObject<MyFeed>(json, settings);
var quote = quoteWrapper.Quote;
}
}
public class MyFeed
{
[JsonProperty("MyFeed")]
public Quote Quote { get; set; }
}
public class Quote
{
[JsonProperty("#Provider")]
public string Provider { get; set; }
[JsonProperty(PropertyName = "MMM")]
public Data Info { get; set; }
}
public class Data
{
[JsonProperty("#name")]
public string name { get; set; }
public decimal low { get; set; }
public decimal high { get; set; }
public decimal change { get; set; }
public decimal pctchange { get; set; }
public decimal ask { get; set; }
public DateTime bid_time { get; set; }
public decimal bid { get; set; }
}
Your Quote class should be Serializable. Either add Serializable attribute to it or DataContract attribute to it with DataMembers.