Unable to correctly parse JSON body - c#

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

Related

Convert Rest API JSON Response into C# object

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"];
}

JSON list converter C#

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.

C#: JSON One to Many Data Parse - SSIS Script Component

Any help would be appreciated. I am trying to parse data from a JSON source file in SSIS (SQL Server Integration Services). I can parse through the data but am getting stuck on parsing the data where there is a 'one to many' relationship. There is a data entity repeated several times ("display_k") -
"responses":
[
{"display_k":"good","answer":null}
,{"display_k":"bad","answer":null}
,{"display_k":"general","answer":"The whole process was Easy. "}
,{"display_k":"would_buy_again","answer":true}
,{"display_k":"happy_with_customer_service","answer":null}
]
The full code is below:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.IO;
//using Newtonsoft.Json;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;
using System.Text;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
var filePath = Connections.Connection.AcquireConnection(null).ToString();
using (var fileContents = new StreamReader(filePath))
while (fileContents.Peek() >= 0)
{
var record = fileContents.ReadLine();
var ser = new DataContractJsonSerializer(typeof(RootObject));
var memStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(record));
var root = ser.ReadObject(memStream) as RootObject;
//reviewables
var CustomerExperienceReview = root.customer_experience_reviews;
foreach (var CER in CustomerExperienceReview)
{
OutputBuffer.AddRow();
OutputBuffer.id = CER.id;
OutputBuffer.branchattribution = CER.branch_attribution;
OutputBuffer.reviewerfirstname = CER.reviewer.first_name;
OutputBuffer.reviewerid = CER.reviewer.id;
// Cannot get the output buffer to show the correct result:
OutputBuffer.responsesdisplaykey = string.Join(",", CER.responses.display_key);
}
}
}
public class Pagination
{
public int total_entries { get; set; }
public int current_page { get; set; }
public int total_pages { get; set; }
public int per_page { get; set; }
public object previous_page { get; set; }
public int next_page { get; set; }
}
public class Summary
{
public Pagination pagination { get; set; }
public int moving_window_size { get; set; }
public SortOrder sort_order { get; set; }
public List<object> sort_orders { get; set; }
}
public class Reviewer
{
public string first_name { get; set; }
public int id { get; set; }
}
public class Respons
{
public string display_key { get; set; }
public object answer { get; set; }
}
public class CustomerExperienceReview
{
public int id { get; set; }
public string branch_attribution { get; set; }
public List<Respons> responses { get; set; }
}
public class RootObject
{
public Summary summary { get; set; }
public List<CustomerExperienceReview> customer_experience_reviews { get; set; }
}
}
You have:
OutputBuffer.responsesdisplaykey = string.Join(",", CER.responses.display_key);
Based on the class definitions, CER.responses is a List<Respons>. If you want a comma-separated list of display keys, you'll need to project the Respons objects to strings.
OutputBuffer.responsesdisplaykey = string.Join(",", CER.responses.Select(r=>r.display_key));

How do I deserialise this JSON?

I haven't done anything with JSON before... so I am probably just missing a step.
Here is an example of the JSON I want to deserialise:
{"item":{"icon":"http://services.runescape.com/m=itemdb_rs/4765_obj_sprite.gif?id=4798","icon_large":"http://services.runescape.com/m=itemdb_rs/4765_obj_big.gif?id=4798","id":4798,"type":"Ammo","typeIcon":"http://www.runescape.com/img/categories/Ammo","name":"Adamant brutal","description":"Blunt adamantite arrow...ouch","current":{"trend":"neutral","price":237},"today":{"trend":"neutral","price":0},"members":"true","day30":{"trend":"positive","change":"+1.0%"},"day90":{"trend":"negative","change":"-0.0%"},"day180":{"trend":"positive","change":"+0.0%"}}}
I put this into "Json 2 C#" and ended up creating this new .cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RSTool.Models
{
public class Current
{
public string trend { get; set; }
public int price { get; set; }
}
public class Today
{
public string trend { get; set; }
public int price { get; set; }
}
public class Day30
{
public string trend { get; set; }
public string change { get; set; }
}
public class Day90
{
public string trend { get; set; }
public string change { get; set; }
}
public class Day180
{
public string trend { get; set; }
public string change { get; set; }
}
public class Item
{
public string icon { get; set; }
public string icon_large { get; set; }
public int id { get; set; }
public string type { get; set; }
public string typeIcon { get; set; }
public string name { get; set; }
public string description { get; set; }
public Current current { get; set; }
public Today today { get; set; }
public string members { get; set; }
public Day30 day30 { get; set; }
public Day90 day90 { get; set; }
public Day180 day180 { get; set; }
}
public class RootObject
{
public Item item { get; set; }
}
}
So, I have the class. I can retrieve the JSON from its location as a string, but I really have no idea how to deserialise it... I have installed Newtonsoft.Json and have tried using PopulateObject and also Deserializer but not with any luck...
Assuming that my JSON is stored as a string called "json", how would I go about storing that query and then retrieving the item name, for example?
Use:
var deserialized = JsonConvert.DeserializeObject<RootObject>(json);
I just tested this successfully given the code you supplied.
You can then access properties of object as normal:
MessageBox.Show(deserialized.item.name);

How will I get this json into my c# class

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.

Categories