I am completely c# beginner. I am trying to convert json data in c#. I am struggling with the list. As long as I am able to convert basic methods, I have an error in that one with the list. Do you mind to give me some advice how to fix my problem?
Original JSON data
[{"data": {"Temperature": {"data": {"2018-07-04 13:05:00": 20.9224991798401}, "meta": {"units": "Celsius", "name": "Temperature", "theme": "Weather"}}}, "latest": "2018-07-04 13:05:00", "sensor_height": -999, "type": "Weather", "base_height": -999, "geom": {"coordinates": [-1.62469, 54.98274], "type": "Point"}, "active": "True", "name": "sportshall_oat", "source": {"document": null, "fancy_name": "BMS", "db_name": "Bms", "third_party": false, "web_display_name": "BMS"}}]
Main class
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var client = new WebClient();
var text = client.DownloadString("http://uoweb1.ncl.ac.uk/api/v1/sensor/live.json?sensor_name=sportshall_oat&api_key=4dopcdjiu3wtzfl32hn94hbf5ubm3q89jbh18iaxaqdzc10nlgbebqqvxqyt3ymydi59fjnyrmuqtgtdxb1sm5msac");
Rootobject ro = JsonConvert.DeserializeObject<Rootobject>(text);
Console.WriteLine("current time = " + ro.Property1);
Class1 c1 = JsonConvert.DeserializeObject<Class1>(text);
Data data = JsonConvert.DeserializeObject<Data>(text);
Temperature temperature = JsonConvert.DeserializeObject<Temperature>(text);
Console.WriteLine("data = " + temperature.data);
Data1 d1 = JsonConvert.DeserializeObject<Data1>(text);
Meta meta = JsonConvert.DeserializeObject<Meta>(text);
Geom geom = JsonConvert.DeserializeObject<Geom>(text);
Source source = JsonConvert.DeserializeObject<Source>(text);
}
}
}
JSON data (generated by Visual studio)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public Data data { get; set; }
public string latest { get; set; }
public int sensor_height { get; set; }
public string type { get; set; }
public int base_height { get; set; }
public Geom geom { get; set; }
public string active { get; set; }
public string name { get; set; }
public Source source { get; set; }
}
public class Data
{
public Temperature Temperature { get; set; }
}
public class Temperature
{
public Data1 data { get; set; }
public Meta meta { get; set; }
}
public class Data1
{
public float _20180704130500 { get; set; }
}
public class Meta
{
public string units { get; set; }
public string name { get; set; }
public string theme { get; set; }
}
public class Geom
{
public float[] coordinates { get; set; }
public string type { get; set; }
}
public class Source
{
public object document { get; set; }
public string fancy_name { get; set; }
public string db_name { get; set; }
public bool third_party { get; set; }
public string web_display_name { get; set; }
}
}
When I am trying to run my program the console is crushed. After debugging I can tell where the problem is, but I don't know how to fix it. There is the error message
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type 'ConsoleApp2.Rootobject'
because the type requires a JSON object (e.g. {"name":"value"}) to
deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g.
{"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array.
Thank you all in advance.
There's a couple of problems with your code.
Since the JSON is surrounded by [...], it means it's an array or items so you need to use a List (or similar) structure. In your case, you can drop the Rootobject class completely and deserialise directly to a List<Class1>. For example:
var result = JsonConvert.DeserializeObject<List<Class1>>(json);
The Data1 class is using a date as the property name. I would suggest dropping that class completely and modify thre Temperature class to use a Dictonary<DateTime, float>:
public class Temperature
{
public Dictionary<DateTime, float> data { get; set; }
public Meta meta { get; set; }
}
And now you can cope with any DateTime being passed in, you would use it like this:
var data = obj[0].data.Temperature.data;
Console.WriteLine($"The temperature on {data.Key} was {data.Value}");
Your RootObject is wrong, and Class1 is badly named but it is essentially the right structure to deserialize the data - however the data is an array of Class1's. You can use a List<Class1> or Class1[] (array) - either should work:
var client = new WebClient();
var text = client.DownloadString("http://uoweb1.ncl.ac.uk/api/v1/sensor/live.json?sensor_name=sportshall_oat&api_key=4dopcdjiu3wtzfl32hn94hbf5ubm3q89jbh18iaxaqdzc10nlgbebqqvxqyt3ymydi59fjnyrmuqtgtdxb1sm5msac");
var result = JsonConvert.DeserializeObject<List<Class1>>(text);
You dont need to separately deserialize all the sub parts, eg you can do this:
var name = result[0].name;
(Note: your list has a single item so you need to ask the list for item with index 0, and then whatever property you're after)
I wont repeat the warning about your Temperature class, but see #DavidG's answer
Then you need a model. Based on your JSON it will result in something like this.
public class RootObject
{
public Data data { get; set; }
public DateTime latest { get; set; }
public int sensor_height { get; set; }
public string type { get; set; }
public int base_height { get; set; }
public Geom geom { get; set; }
public string active { get; set; }
public string name { get; set; }
public Source source { get; set; }
}
public class Data
{
public Temperature Temperature { get; set; }
public Meta meta { get; set; }
}
public class Geom
{
public float[] coordinates { get; set; }
public string type { get; set; }
}
public class Source
{
Public string document { get; set; }
Public string fancy_name { get; set; }
Public string db_name { get; set; }
Public string third_party { get; set; }
Public string web_display_name { get; set; }
}
public class Temperature
{
public string data { get; set; }
}
public class Meta
{
Public string units { get; set; }
Public string name { get; set; }
Public string theme { get; set; }
}
After the creation of a model you simply use this.
var result = JsonConvert.DeserializeObject<RootObject>(your_json_string);
Then you can access to the objects like this:
result.data..
result.latest...
and so on.
Related
I'm trying to convert a data from a nested JSon file to C# Model, and I get this error :
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[convert_json_to_model.Fields]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'nhits', line 1, position 9.
Here is some data
{
"nhits":17933,
"parameters":{
"dataset":[
"osm-fr-bars#babel"
],
"rows":3,
"start":0,
"format":"json",
"timezone":"UTC"
},
"records":[
{
"datasetid":"osm-fr-bars#babel",
"recordid":"d95394fd7d34aa34aa9b236661bce9cda534a8ab",
"fields":{
"other_tags":"{\"cuisine\": \"tapas\", \"ref:FR:CRTA\": \"RESAQU047V506W6V\",
\"capacity\": \"14\", \"description\": \"Tous les jours \u00e0 partir de 7h\",
\"source\": \"BDOrtho IGN; Cadastre M\u00e0J 2015; Sirtaqui\", \"outdoor_seating\":
\"yes\", \"source:ref:FR:CRTA\": \"Sirtaqui\"}",
"name":"Au boin coin",
"geo_point_2d":[
44.0549704,
0.2603921
],
"phone":"+33 5 53 65 67 45"
},
"geometry":{
"type":"Point",
"coordinates":[
0.2603921,
44.0549704
]
}
Here is the link of my Json file to see all fields :
https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars%40babel&rows=30
Here is my model after using the tool JSON to C#
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
Here is the method to deserialize
static async Task Main(string[] args)
{
string url = "https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars%40babel&rows=30";
HttpClient httpClient = new HttpClient();
try
{
var httpResponseMessage = await httpClient.GetAsync(url);
string jsonResponse = await httpResponseMessage.Content.ReadAsStringAsync();
List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
In the main, the HTTP response is deserialized to the type List<Fields>. But the JSON rather corresponds the type Root. Try :
//List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
Please organise your model well.
Fields myBars = JsonConvert.DeserializeObject<Fields>(jsonResponse);
or
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
fix your class Root and add a missed Parameters class
Root data =JsonConvert.DeserializeObject<Root>(jsonResponse);
List<Fields> myBars = data.Records.Select(f=> f.Fields).ToList();
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
public partial class Root
{
[JsonProperty("nhits")]
public long Nhits { get; set; }
[JsonProperty("parameters")]
public Parameters Parameters { get; set; }
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public partial class Parameters
{
[JsonProperty("dataset")]
public List<string> Dataset { get; set; }
[JsonProperty("rows")]
public long Rows { get; set; }
[JsonProperty("start")]
public long Start { get; set; }
[JsonProperty("format")]
public string Format { get; set; }
[JsonProperty("timezone")]
public string Timezone { get; set; }
}
Problem solved, i changed the loop from foreach to for with index, and i should have added this parameters :
for (int i=0;i<myBars.Records.Count();i++)
{
Console.WriteLine($"{myBars.Records[i].Fields.Name}");
}
I am successfully able to retrieve the JSON body from a URL in Visual Studio 2019 using Newtonsoft library. However I'm having difficulty in parsing out the only variable I am interested in.
I've tried to follow some guides on here that I don't seem to have either implemented correctly or haven't fully understood (I'm pretty new to this).
e.g.
Unexpected character encountered while parsing API response
RAW JSON:
{"deviceId":37,"longMacAddress":"5884e40000000439","shortMacAddress":259,"hoplist":"(259,3)","associationTime":"2019-06-10 22:43:54","lifeCheckInterval":5,"lastLiveCheck":"2019-06-11 07:11:37","onlineStatus":1,"txPowerValue":14,"deviceType":1,"frequencyBand":1,"lastLivecheck":"2019-06-11 07:11:36","disassociationState":0,"firmwareUpdateActivated":0,"firmwareUpdatePackagesSent":0,"firmwareUpdatePackagesUnsent":0,"firmwareUpdateInProgress":0,"deviceIdOem":"-1","deviceNameOem":"-1","deviceCompanyOem":"-1","binaryInputCount":0,"binaryOutputCount":0,"analogInputCount":0,"characterStringCount":1,"location":[{"location":"UK","locationWriteable":1,"changedAt":"2019-06-10 23:40:50"}],"description":[{"description":"DevKit","descriptionWriteable":1,"changedAt":"2019-06-10 23:40:54"}],"binaryInput":[],"binaryOutput":[],"analogInput":[],"characterString":[{"characterString":"149+0.0+99+26.5+0","characterStringWriteable":1,"changedAt":"2019-06-11 06:45:02"}]}
MY MAIN CODE:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace API_JSON_1
{
class Program
{
static void Main(string[] args)
{
var client = new WebClient();
var JSON = client.DownloadString("http://192.168.0.254:8000/nodes/longmac/5884e40000000439");
Console.WriteLine(JSON);
Console.WriteLine("----------------------------------------------");
CharacterString CSV = JsonConvert.DeserializeObject<CharacterString>(JSON);
Console.WriteLine("Sensor data: " + CSV.CharacterStringCharacterString);
}
}
}
MY CHARACTER STRING CLASS:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace API_JSON_1
{
public class CharacterStrings
{
public CharacterStrings CharString { get; set; }
}
public class CharacterString
{ public string CharacterStringCharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTimeOffset ChangedAt { get; set; }
}
}
OUTPUT TO THE CONSOLE:
{"deviceId":37,"longMacAddress":"5884e40000000439","shortMacAddress":259,"hoplis
t":"(259,3)","associationTime":"2019-06-10 22:43:54","lifeCheckInterval":5,"last
LiveCheck":"2019-06-11 06:56:37","onlineStatus":1,"txPowerValue":14,"deviceType"
:1,"frequencyBand":1,"lastLivecheck":"2019-06-11 06:56:33","disassociationState"
:0,"firmwareUpdateActivated":0,"firmwareUpdatePackagesSent":0,"firmwareUpdatePac
kagesUnsent":0,"firmwareUpdateInProgress":0,"deviceIdOem":"-1","deviceNameOem":"
-1","deviceCompanyOem":"-1","binaryInputCount":0,"binaryOutputCount":0,"analogIn
putCount":0,"characterStringCount":1,"location":[{"location":"UK","locati
onWriteable":1,"changedAt":"2019-06-10 23:40:50"}],"description":[{"description"
:"DevKit","descriptionWriteable":1,"changedAt":"2019-06-10 23:40:54"}],"binaryIn
put":[],"binaryOutput":[],"analogInput":[],"characterString":[{"characterString"
:"149+0.0+99+26.5+0","characterStringWriteable":1,"changedAt":"2019-06-11 06:45:
02"}]}
----------------------------------------------
Sensor data:
Press any key to continue . . .
Obviously I was expecting/hoping that the penultimate line there would read:
"Sensor data: 149+0.0+99+26.5+0"
In order for this to work you have to modify your classes like this:
public class CharacterStrings
{
public List<CharacterStringObject> CharacterString { get; set; }
}
public class CharacterStringObject
{
public string CharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTime ChangedAt { get; set; }
}
After that, after you read your JSON like that:
CharacterString CSV = JsonConvert.DeserializeObject<CharacterString>(JSON);
You end up with List<CharacterStringObject> with one element in it. So you take the first one like that and print it:
Console.WriteLine("Sensor data: " + CSV.CharacterString.First().CharacterString);
Cheers,
Edit: Tested it locally with your given JSON, works fine
Welcome to StackOverflow!
Something you need to keep in mind when converting a json string to an object (ie: Deserialize) is that the object to which you are converting the string into needs to match the format of the json string. In your case, the json string does not match the object to which you are converting.
Once you have the correct object, this will give you the output you want:
static void Main(string[] args)
{
string JSON = "{\"deviceId\":37,\"longMacAddress\":\"5884e40000000439\",\"shortMacAddress\":259,\"hoplist\":\"(259,3)\",\"associationTime\":\"2019-06-10 22:43:54\",\"lifeCheckInterval\":5,\"lastLiveCheck\":\"2019-06-11 07:11:37\",\"onlineStatus\":1,\"txPowerValue\":14,\"deviceType\":1,\"frequencyBand\":1,\"lastLivecheck\":\"2019-06-11 07:11:36\",\"disassociationState\":0,\"firmwareUpdateActivated\":0,\"firmwareUpdatePackagesSent\":0,\"firmwareUpdatePackagesUnsent\":0,\"firmwareUpdateInProgress\":0,\"deviceIdOem\":\"-1\",\"deviceNameOem\":\"-1\",\"deviceCompanyOem\":\"-1\",\"binaryInputCount\":0,\"binaryOutputCount\":0,\"analogInputCount\":0,\"characterStringCount\":1,\"location\":[{\"location\":\"UK\",\"locationWriteable\":1,\"changedAt\":\"2019-06-10 23:40:50\"}],\"description\":[{\"description\":\"DevKit\",\"descriptionWriteable\":1,\"changedAt\":\"2019-06-10 23:40:54\"}],\"binaryInput\":[],\"binaryOutput\":[],\"analogInput\":[],\"characterString\":[{\"characterString\":\"149+0.0+99+26.5+0\",\"characterStringWriteable\":1,\"changedAt\":\"2019-06-11 06:45:02\"}]}";
Console.WriteLine(JSON);
Console.WriteLine("----------------------------------------------");
RootObject CSV = JsonConvert.DeserializeObject<RootObject>(JSON);
// Option 1: Loop over the items in your List<CharacterString>...
foreach (var cs in CSV.characterString)
{
Console.WriteLine("Sensor data: " + cs.characterString);
}
// Option 2: Or, if you know there is only one in the list...
Console.WriteLine("Sensor data: " + CSV.characterString.First().characterString);
}
EDIT to explain the code above: Because characterString is a List<CharacterString>, it's technically possible that you could have more than one item in that list. Option 1: If you want, you can loop through that list to display the items in it. But if you know for certain that there will only be one item in the list, then, Option 2: You can just display the .First() item in the list.
I took the json sting you gave us, and using this handy website (http://json2csharp.com/#) I converted it into the following classes:
public class RootObject
{
public int deviceId { get; set; }
public string longMacAddress { get; set; }
public int shortMacAddress { get; set; }
public string hoplist { get; set; }
public string associationTime { get; set; }
public int lifeCheckInterval { get; set; }
public string lastLiveCheck { get; set; }
public int onlineStatus { get; set; }
public int txPowerValue { get; set; }
public int deviceType { get; set; }
public int frequencyBand { get; set; }
public string lastLivecheck { get; set; }
public int disassociationState { get; set; }
public int firmwareUpdateActivated { get; set; }
public int firmwareUpdatePackagesSent { get; set; }
public int firmwareUpdatePackagesUnsent { get; set; }
public int firmwareUpdateInProgress { get; set; }
public string deviceIdOem { get; set; }
public string deviceNameOem { get; set; }
public string deviceCompanyOem { get; set; }
public int binaryInputCount { get; set; }
public int binaryOutputCount { get; set; }
public int analogInputCount { get; set; }
public int characterStringCount { get; set; }
public List<Location> location { get; set; }
public List<Description> description { get; set; }
public List<object> binaryInput { get; set; }
public List<object> binaryOutput { get; set; }
public List<object> analogInput { get; set; }
public List<CharacterString> characterString { get; set; }
}
public class Location
{
public string location { get; set; }
public int locationWriteable { get; set; }
public string changedAt { get; set; }
}
public class Description
{
public string description { get; set; }
public int descriptionWriteable { get; set; }
public string changedAt { get; set; }
}
public class CharacterString
{
public string characterString { get; set; }
public int characterStringWriteable { get; set; }
public string changedAt { get; set; }
}
The CharacterString property in the json is an array of objects. Also the first property in those objects is characterString. Below is a working example
Output is Sensor Data: 149+0.0+99+26.5+0
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace SOTest
{
class Program
{
static void Main(string[] args)
{
var json =
"{\"deviceId\":37,\"longMacAddress\":\"5884e40000000439\",\"shortMacAddress\":259,\"hoplist\":\"(259,3)\",\"associationTime\":\"2019-06-10 22:43:54\",\"lifeCheckInterval\":5,\"lastLiveCheck\":\"2019-06-11 07:11:37\",\"onlineStatus\":1,\"txPowerValue\":14,\"deviceType\":1,\"frequencyBand\":1,\"lastLivecheck\":\"2019-06-11 07:11:36\",\"disassociationState\":0,\"firmwareUpdateActivated\":0,\"firmwareUpdatePackagesSent\":0,\"firmwareUpdatePackagesUnsent\":0,\"firmwareUpdateInProgress\":0,\"deviceIdOem\":\"-1\",\"deviceNameOem\":\"-1\",\"deviceCompanyOem\":\"-1\",\"binaryInputCount\":0,\"binaryOutputCount\":0,\"analogInputCount\":0,\"characterStringCount\":1,\"location\":[{\"location\":\"UK\",\"locationWriteable\":1,\"changedAt\":\"2019-06-10 23:40:50\"}],\"description\":[{\"description\":\"DevKit\",\"descriptionWriteable\":1,\"changedAt\":\"2019-06-10 23:40:54\"}],\"binaryInput\":[],\"binaryOutput\":[],\"analogInput\":[],\"characterString\":[{\"characterString\":\"149+0.0+99+26.5+0\",\"characterStringWriteable\":1,\"changedAt\":\"2019-06-11 06:45:02\"}]}";
var obj = JsonConvert.DeserializeObject<CharacterStrings>(json);
Console.WriteLine($"Sensor Data: {obj.CharacterString.First().CharacterString}");
Console.ReadKey();
}
public class CharacterStrings
{
public List<Characters> CharacterString { get; set; }
}
public class Characters
{ public string CharacterString { get; set; }
public long CharacterStringWriteable { get; set; }
public DateTime ChangedAt { get; set; }
}
}
}
You are defining the CSV object with CharacterSting. I should be CharacterStrings and Inside the CharacterStrings class it should to be array because your JSON is an array
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 very new to C# and Visualstudio2017 and have been stuck on this for literally weeks. Searching the net but not finding results relating to this that i can understand properly. What i am trying to do is get json data from
https://zkillboard.com/api/stats/characterID/224802743/
then convert it into usable data that i can get and display certain data in certain textboxes. I used https://quicktype.io/ to convert the json into C# array.
MainForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using ZKILLBOARDDATA;
namespace MainProgram
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
public async void Btn_submit_ClickAsync(object sender, EventArgs e)
{
var remoteUri = "https://zkillboard.com/api/stats/characterID/224802743/";
var myWebClient = new WebClient();
myWebClient.Headers.Add("user-agent", "C# App testing");
var jsonString = await myWebClient.DownloadStringTaskAsync(remoteUri);
var data = GettingStarted.FromJson(jsonString);
}
}
}
Zkill.cs
using Newtonsoft.Json;
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using ZKILLBOARDDATA;
//
// var data = GettingStarted.FromJson(jsonString);
//
namespace ZKILLBOARDDATA
{
public partial class GettingStarted
{
[JsonProperty("attackers")]
public Attacker[] Attackers { get; set; }
[JsonProperty("killmail_id")]
public long KillmailId { get; set; }
[JsonProperty("killmail_time")]
public string KillmailTime { get; set; }
[JsonProperty("moon_id")]
public long? MoonId { get; set; }
[JsonProperty("solar_system_id")]
public long SolarSystemId { get; set; }
[JsonProperty("victim")]
public Victim Victim { get; set; }
[JsonProperty("war_id")]
public long? WarId { get; set; }
[JsonProperty("zkb")]
public Zkb Zkb { get; set; }
}
public partial class Zkb
{
[JsonProperty("awox")]
public bool Awox { get; set; }
[JsonProperty("fittedValue")]
public double FittedValue { get; set; }
[JsonProperty("hash")]
public string Hash { get; set; }
[JsonProperty("locationID")]
public long LocationID { get; set; }
[JsonProperty("npc")]
public bool Npc { get; set; }
[JsonProperty("points")]
public long Points { get; set; }
[JsonProperty("solo")]
public bool Solo { get; set; }
[JsonProperty("totalValue")]
public double TotalValue { get; set; }
}
public partial class Victim
{
[JsonProperty("alliance_id")]
public long? AllianceId { get; set; }
[JsonProperty("character_id")]
public long? CharacterId { get; set; }
[JsonProperty("corporation_id")]
public long CorporationId { get; set; }
[JsonProperty("damage_taken")]
public long DamageTaken { get; set; }
[JsonProperty("items")]
public Item[] Items { get; set; }
[JsonProperty("position")]
public Position Position { get; set; }
[JsonProperty("ship_type_id")]
public long ShipTypeId { get; set; }
}
public partial class Position
{
[JsonProperty("x")]
public double X { get; set; }
[JsonProperty("y")]
public double Y { get; set; }
[JsonProperty("z")]
public double Z { get; set; }
}
public partial class Item
{
[JsonProperty("flag")]
public long Flag { get; set; }
[JsonProperty("item_type_id")]
public long ItemTypeId { get; set; }
[JsonProperty("items")]
public Item[] Items { get; set; }
[JsonProperty("quantity_destroyed")]
public long? QuantityDestroyed { get; set; }
[JsonProperty("quantity_dropped")]
public long? QuantityDropped { get; set; }
[JsonProperty("singleton")]
public long Singleton { get; set; }
}
public partial class Attacker
{
[JsonProperty("alliance_id")]
public long? AllianceId { get; set; }
[JsonProperty("character_id")]
public long? CharacterId { get; set; }
[JsonProperty("corporation_id")]
public long? CorporationId { get; set; }
[JsonProperty("damage_done")]
public long DamageDone { get; set; }
[JsonProperty("faction_id")]
public long? FactionId { get; set; }
[JsonProperty("final_blow")]
public bool FinalBlow { get; set; }
[JsonProperty("security_status")]
public double SecurityStatus { get; set; }
[JsonProperty("ship_type_id")]
public long? ShipTypeId { get; set; }
[JsonProperty("weapon_type_id")]
public long? WeaponTypeId { get; set; }
}
public partial class GettingStarted
{
public static GettingStarted[] FromJson(string json) => JsonConvert.DeserializeObject<GettingStarted[]>(json, Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this GettingStarted[] self) => JsonConvert.SerializeObject(self, Converter.Settings);
}
public class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
};
}
}
Here is the error message i am getting from VS2017.
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'ZKILLBOARDDATA.GettingStarted[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'allTimeSum', line 1, position 14.
Try this
var remoteUri = "https://zkillboard.com/api/stats/characterID/224802743/";
var myWebClient = new WebClient();
myWebClient.Headers.Add("user-agent", "C# App testing");
myWebClient.Headers.Add("content-type", "application/json");
var jsonString = myWebClient.DownloadStringTaskAsync(remoteUri).Result;
var obj = JsonConvert.DeserializeObject(jsonString);
//OR
var obj = JsonConvert.DeserializeObject<YourModel>(jsonString);
I don't think you need this in your model
public partial class GettingStarted
{
public static GettingStarted[] FromJson(string json) => JsonConvert.DeserializeObject<GettingStarted[]>(json, Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this GettingStarted[] self) => JsonConvert.SerializeObject(self, Converter.Settings);
}
public class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
};
}
I had the same problem; I solved it by using the new default System.Text.Json.JsonSerializer.Deserialize instead of the Newtonsoft's
using System.Text.Json;
var obj = JsonSerializer.Deserialize<YourMODEL>(jsonStr);
p.s. https://quicktype.io is great (although seems somewhat outdated for C#); I've also tried http://json2csharp.com but my json file is big and it froze up.
Also sometimes (in particularly for deeply nested complex json) quicktype doesn't add the list/array type; e.g. MyObj instead of List<MyObj>.
Sometimes it is possible to "fix" it by picking T[] first and then List from the website's generation menu option Use T[] or List<T>.
I would like to read in a json respons to my c# class for learning and having problem with it.
This is the main code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var webClient = new System.Net.WebClient();
var json = webClient.DownloadString("https://api.trafiklab.se/samtrafiken/resrobotstops/GetDepartures.json?key=[KEY]&apiVersion=2.2&locationId=7420752&coordSys=RT90");
This url will return this json
{"getdeparturesresult":{"departuresegment":[{"departure":{"location":
{"#id":"7420752","#x":"1271307","#y":"6404493","name":"Göteborg Brunnsparken"}
,"datetime":"2014-12-10 12:27"},"direction":"Göteborg KÄlltorp","segmentid":
{"mot":{"#displaytype":"S","#type":"SLT","#text":"SpÄrvagn"},"carrier":
{"name":"VĂ€sttrafik","url":"http:\/\/www.vasttrafik.se\/","id":"279","number":"3"}}},
The first problem is that when generating a c# class it will complain about the # in the variable name. How can this be fixed? I mean I cant change the json respons. That is what I get. My guess would be this:
getdeparturesresult.departuresegment.departure.location["#x"]);
The second is how will I write to get it in to my class? What should be used?
I have tried this but then it will complain about my RootObject:
string json = r.ReadToEnd();
List<RootObject> items = JsonConvert.DeserializeObject<List<RootObject>>(json);
Lets say I got a class like this
public class Location
{
public string id { get; set; }
public string x { get; set; }
public string y { get; set; }
public string name { get; set; }
}
public class Departure
{
public Location location { get; set; }
public string datetime { get; set; }
}
public class Mot
{
public string displaytype { get; set; }
public string type { get; set; }
public string text { get; set; }
}
public class Carrier
{
public string name { get; set; }
public string url { get; set; }
public string id { get; set; }
public string number { get; set; }
}
public class Segmentid
{
public Mot mot { get; set; }
public Carrier carrier { get; set; }
}
public class Departuresegment
{
public Departure departure { get; set; }
public string direction { get; set; }
public Segmentid segmentid { get; set; }
}
public class Getdeparturesresult
{
public Departuresegment departuresegment { get; set; }
}
public class RootObject
{
public Getdeparturesresult getdeparturesresult { get; set; }
}
I have also tried this
dynamic array = JsonConvert.DeserializeObject(json);
foreach (var item in array)
{
Console.WriteLine("{0}", item);
}
This will printout whats in the json. But how do I get it to be read into my class? I cant figure it out. It must be simple but I cant get it right.
You only need to change like:
public class Getdeparturesresult
{
public IEnumerable<Departuresegment> departuresegment { get; set; }
}
You can still use the Json.net serializer (JsonConvert).
Edit:
To handle the "#id" property you can do this:
[JsonProperty("#id")]
public string id { get; set; }
You could accomplish that with JavaScriptSerializer.
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(json);
It worked for me, but I had to change the type of Getdeparturesresult.departuresegment property to an array:
public class Getdeparturesresult
{
public Departuresegment[] departuresegment { get; set; }
}
Update:
To deserialize JSON properties with special characters with .NET, you can use DataContractJsonSerializer.
RootObject root;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
root = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(RootObject)).ReadObject(stream) as RootObject;
But your code will have to get verbose. You need to mark every class with [DataContract] and every property with [DataMember] attributes. For the properties whose names are not equal to those of the source, use [DataMember(Name = "#fancy_name")].
[DataContract]
public class Location
{
[DataMember(Name = "#id")]
public string id { get; set; }
[DataMember(Name = "#x")]
public string x { get; set; }
[DataMember(Name = "#y")]
public string y { get; set; }
[DataMember]
public string name { get; set; }
}
// etc.