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 having trouble understanding how to deserialze a JSON string into a class that's coming back from an API I am calling...
Normally, I copy the returned JSON and in Visual Studio I paste special as JSON to Class. It normally works perfectly.
But, with this API the class that is generated contains hardcoded values that might be different the next time I call the API...
This is the JSON that comes back from the API:
{"content":{"type":"getTips_answer","total":61,"scan":1,"tips":{"2360626":[["3","4","6","8","10","25"],["9","11","22","27","34","40"],["4","12","25","27","29","30"],["4","6","7","10","41","47"],["14","17","20","40","41","42"],["17","20","22","26","30","41"],["1","3","18","21","28","39"],["5","10","13","19","25","39"],["17","25","33","38","42","44"],["5","11","16","25","43","45"],["5","9","25","27","38","44"],["7","19","27","32","46","48"],["20","21","28","34","37","48"],["10","12","18","35","43","47"],["3","6","9","17","29","42"],["22","26","28","36","43","47"],["7","13","24","30","45","48"],["3","5","14","19","23","27"],["9","14","15","16","22","40"],["10","18","26","36","41","46"],["2","19","23","33","38","42"]],"2360710":[["1","15","17","21","25","33"]],"2361097":[["1","3","5","27","35","41"],["3","11","12","24","27","48"],["8","11","13","33","34","48"],["2","10","29","31","41","46"]],"2362535":[["10","15","33","35","36","44"],["5","8","11","18","26","44"]],"2363152":[["6","7","10","13","35","37"],["1","9","14","29","42","49"],["23","24","26","32","35","45"],["1","2","11","18","22","39"]],"2363573":[["8","11","16","18","34","36"],["12","13","23","25","27","35"],["2","7","13","23","41","49"],["3","6","9","15","21","41"],["9","10","16","20","30","34"],["15","18","40","44","46","48"]],"2363902":[["17","19","24","26","33","48"]],"2364026":[["8","17","20","33","34","47"]],"2364405":[["10","17","23","38","41","45"],["9","13","27","33","36","41"]],"2365222":[["4","5","7","9","18","24"],["10","12","16","26","43","45"],["1","5","24","26","43","47"],["11","12","17","20","36","48"],["3","11","13","17","20","27"],["2","6","28","38","42","46"],["9","13","19","20","25","31"],["2","5","7","8","25","27"],["1","19","21","23","33","36"],["17","19","23","33","38","47"],["14","27","28","32","39","42"],["18","26","30","32","42","46"]],"2365522":[["2","24","25","31","42","48"],["13","16","31","39","43","45"]],"2365651":[["7","20","22","35","40","41"],["5","13","20","30","43","47"],["5","16","18","31","34","44"],["6","8","15","17","44","45"],["7","11","26","27","29","47"]]},"success":true,"errors":[]}}
This is the class that Visual Studio generates from the above JSON:
public class Rootobject
{
public Content content { get; set; }
}
public class Content
{
public string type { get; set; }
public int total { get; set; }
public int scan { get; set; }
public Tips tips { get; set; }
public bool success { get; set; }
public object[] errors { get; set; }
}
public class Tips
{
public string[][] _2360626 { get; set; }
public string[][] _2360710 { get; set; }
public string[][] _2361097 { get; set; }
public string[][] _2362535 { get; set; }
public string[][] _2363152 { get; set; }
public string[][] _2363573 { get; set; }
public string[][] _2363902 { get; set; }
public string[][] _2364026 { get; set; }
public string[][] _2364405 { get; set; }
public string[][] _2365222 { get; set; }
public string[][] _2365522 { get; set; }
public string[][] _2365651 { get; set; }
}
My problem is that if you look at the Tips class it contains values like _2360626 which might not be there next time.
How to I write a class that I can deserialize this string into that is "dynamic"? if that is the right description?
Thanks
Just declare tips as Dictionary<string,List<List<string>>>
var obj = JsonConvert.DeserializeObject<RootObject>(json); //Json.Net
//or
//var obj = new JavaScriptSerializer().Deserialize<RootObject>(json);
public class Content
{
public string type { get; set; }
public int total { get; set; }
public int scan { get; set; }
public Dictionary<string,List<List<string>>> tips { get; set; }
public bool success { get; set; }
public List<object> errors { get; set; }
}
public class RootObject
{
public Content content { get; set; }
}
I think you'll have to put aside this idea of creating a statically typed class in C# to model this JSON. JSON (and javascript) is not typed so there's not guarantee that it will always fit into such a class (as you've discovered).
I would suggest using one of the C# JSON parsing libraries you'll find referenced here:
http://json.org/
JSON.Net (http://james.newtonking.com/pages/json-net.aspx) sounds popular.
Link that in your project and then use it to dynamically parse the JSON you're receiving from your API call and then do whatever you need to do with the result.
I've got an application that is receiving a JSON response. I've been trying to get it to deserialize, so I can more easily use the data in the application, but after going through several other articles on how to get this to work, I haven't had any success. The List is always empty at the end of the deserialize. The test JSON data is below, and below that is my current code.
{"vehicles":{"size":10,"next":10,"vehicle":[{"vin":"5GZCZ33Z47S000016","make":"Saturn","model":"Saturn Vue","year":2007,"manufacturer":"GM","phone":5002022424,"unitType":"EMBEDDED","primaryDriverId":450984739,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/5GZCZ33Z47S000016","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984739"},{"vin":"1G6DA67VX80000014","make":"Cadillac","model":"STS AWD","year":2008,"manufacturer":"GM","phone":7039277239,"unitType":"EMBEDDED","primaryDriverId":450984752,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G6DA67VX80000014","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984752"},{"vin":"1GNFC26069R000015","make":"Cadillac","model":"Suburban (4X2) 4 door","year":2009,"manufacturer":"GM","phone":2815079899,"unitType":"EMBEDDED","primaryDriverId":450984738,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GNFC26069R000015","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984738"},{"vin":"1GKUKEEF9AR000010","make":"GMC","model":"Denali","year":2010,"manufacturer":"General Motors","phone":3132200010,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GKUKEEF9AR000010","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"5TFHW5F15AX000013","make":"Toyota","model":"Tundra 4WD Truck","year":2010,"manufacturer":"Toyota","phone":3372413717,"unitType":"FMV","primaryDriverId":450984766,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/5TFHW5F15AX000013","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984766"},{"vin":"1G1PJ5S95B7000009","make":"Chevrolet","model":"Cruze","year":2011,"manufacturer":"General Motors","phone":8035553074,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G1PJ5S95B7000009","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"2CNALPEC3B6000001","make":"Chevrolet","model":"Equinox","year":2011,"manufacturer":"General Motors","phone":3135450001,"unitType":"EMBEDDED","primaryDriverId":450984732,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/2CNALPEC3B6000001","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984732"},{"vin":"1GCRCSE09BZ000005","make":"Chevrolet","model":"Silverado Crew Cab","year":2011,"manufacturer":"General Motors","phone":8035553074,"unitType":"EMBEDDED","primaryDriverId":450984732,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1GCRCSE09BZ000005","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450984732"},{"vin":"1G1RD6E47BU000008","make":"Chevrolet","model":"Volt","year":2011,"manufacturer":"General Motors","phone":3139030008,"unitType":"EMBEDDED","primaryDriverId":548392002,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G1RD6E47BU000008","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/548392002"},{"vin":"1G6DH5E53C0000003","make":"Cadillac","model":"CTS Coupe","year":2012,"manufacturer":"General Motors","phone":3136440003,"unitType":"EMBEDDED","primaryDriverId":450438292,"url":"https:\/\/developer.gm.com\/api\/v1\/account\/vehicles\/1G6DH5E53C0000003","primaryDriverUrl":"https:\/\/developer.gm.com\/api\/v1\/account\/subscribers\/450438292"}]}}
This is the function from the Main Form that is handling passing the info into objects.
void Deserialize(IRestResponse response)
{
string workingString = response.Content;
var list = new JavaScriptSerializer().Deserialize<List<GMVehicles>>(workingString);
}
These are the classes that the deserialzer should be putting the data
public class GMVehicles
{
public Vehicle vehicle { get; set; }
}
public class Vehicle
{
public string vin { get; set; }
public string make { get; set; }
public string model { get; set; }
public string year { get; set; }
public string manufacturer { get; set; }
public string phone { get; set; }
public string unitType { get; set; }
public string primaryDriverId { get; set; }
public string url { get; set; }
public string primaryDriverUrl { get; set; }
}
What am I doing wrong?
Your Vehicle class is fine. Now you need a wrapper around your GMVehicles class:
public class Root
{
public GMVehicles Vehicles { get; set; }
}
also your GMVehicles is wrong, it should contain a collection (because the vehicle property in your JSON is a list, not an object):
public class GMVehicles
{
public Vehicle[] Vehicle { get; set; }
}
Alright, now you deserialize the root:
void Deserialize(IRestResponse response)
{
string workingString = response.Content;
var root = new JavaScriptSerializer().Deserialize<Root>(workingString);
Vehicle[] list = root.Vehicles.Vehicle;
// ... do something with the list of vehicles here
}