Extract specific data from JSON - c#

I have the following code in my app (using Newton.Json):
var data = JsonConvert.DeserializeObject(responseValue).ToString();
Using the following code:
Console.WriteLine(data);
I get:
{
"result": "some random string goes here",
"error": null,
"id": "1"
}
How do I get the string from the result part of the JSON in the data variable, and put it into its own variable for later use?

If you have a C# class that corresponds to the "shape" of the JSON (same properties with the same data type):
public class ResponseType
{
public string Result { get; set; }
public string Error { get; set; }
public int Id { get; set; }
}
you can do:
ResponseType data = JsonConvert.DeserializeObject<ResponseType>(responseValue);
and then access each property of that class:
string result = data.Result;

This can be done without deserialization.
var json = JObject.Parse(responseValue);
var result = json["result"];
Open namespace.
using Newtonsoft.Json.Linq;

Related

Deserialize JSON and assign to model

As part of my web api, I'm getting the following JSON returned.
["{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}"]
What I'm wanting to do is grab the value next to Filenameand assign it to my models Filename parameter.
In my project I've created a unit test to experiment with grabbing that value, but each attempt I've making is failing.
In my test I have following DTO Model:
public class HangfireTestDTO
{
public string InputType { get; set; }
public string Filename { get; set; }
}
Then my text logic is this:
[Fact]
public void TestDTO()
{
string data =
"[\"{\\\"InputType\\\":12,\\\"EngineSubType\\\":2,\\\"Filename\\\":\\\"targetFile.csv\\\",\\\"FileExtensionType\\\":\\\".csv\\\",\\\"IsLoadFile\\\":true,\\\"LoadContextId\\\":4120,\\\"ReportingDate\\\":\\\"2019-05-31T00:00:00\\\",\\\"IsSuccess\\\":false}\"]";
// fails here
var arguments = System.Text.Json.JsonSerializer.Deserialize<HangfireTestDTO>(data);
// This is wrong - ignore for now
Assert.Equal("targetFile.csv", arguments.ToString());
}
When I debug the above in my test it tells me the following:
The JSON value could not be converted to MyProject.HangfireTestDTO
My thinking then led me to try again by modifying the deserialize line to the following:
var arguments = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data).FirstOrDefault();
But when running it with the new line, I get the following error:
The JSON value could not be converted to System.Collections.Generic.List
What is it I'm doing wrong?
Your current JSON string is an array of strings. You need to first deserialize the JSON into a list of strings, then deserialize each of those strings as a DTO. Here's a complete example using your JSON:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
public class HangfireTestDTO
{
public int InputType { get; set; }
public int EngineSubType { get; set; }
public string Filename { get; set; }
public string FileExtensionType { get; set; }
}
class Program
{
static void Main()
{
string data =
"[\"{\\\"InputType\\\":12,\\\"EngineSubType\\\":2,\\\"Filename\\\":\\\"targetFile.csv\\\",\\\"FileExtensionType\\\":\\\".csv\\\",\\\"IsLoadFile\\\":true,\\\"LoadContextId\\\":4120,\\\"ReportingDate\\\":\\\"2019-05-31T00:00:00\\\",\\\"IsSuccess\\\":false}\"]";
// First deserialize the single string to a list of strings
List<string> jsonStrings = JsonSerializer.Deserialize<List<string>>(data);
// Then deserialize each of the strings to a DTO.
List<HangfireTestDTO> dtos = jsonStrings
.Select(json => JsonSerializer.Deserialize<HangfireTestDTO>(json))
.ToList();
Console.WriteLine(dtos.Count);
Console.WriteLine(dtos[0].Filename);
}
}
firstly your JSON is wrong
i would expect it too look more like
string data = #"[{""InputType"":12,""EngineSubType"":2,""Filename"":""targetFile.csv"",""FileExtensionType"":"".csv"",""IsLoadFile"":true,""LoadContextId"":4120,""ReportingDate"":""2019-05-31T00:00:00"",""IsSuccess"":false}]"
or
string data = "[{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}]"
second you have wrapped your JSON in [] this means a list of docs so Deserialize<HangfireTestDTO>(data); would be Deserialize<List<HangfireTestDTO>>(data); or some other IEnumerable
then you have serveral data mismatches 12 is a number not a string so InputType should be an int or double, IsSuccess is a bool, etc
finally you have lots of fields in your JSON that aren't on your object you need to explain to c# what to do with them either create the extra properties or provide a KeyValue store it can put them in
ie
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
EDIT following the comment you made if that is really how the data is coming out your DB then its an array of strings where the strings are JSON encoded
in which case you will need to read the strings then parse them after
var jsonlist = JsonSerializer.Deserialize<List<string>>(data);
foreach(string json in jsonlist )
var dto = JsonSerializer.Deserialize<HangfireTestDTO>(json);
The first error is because of InputType. It should be int
public class HangfireTestDTO
{
public int InputType { get; set; }
public string Filename { get; set; }
}
The second error is because of JSON. There is an addition quotation between [ and {. I have tried with below JSON and it worked. Because of this quotation it becomes List<string> and not List<HangfireTestDTO>
[
{
"InputType": 12,
"EngineSubType": 2,
"Filename": "targetFile.csv",
"FileExtensionType": ".csv",
"IsLoadFile": true,
"LoadContextId": 4120,
"ReportingDate": "2019-05-31T00:00:00",
"IsSuccess": false
}
]
And looking at the JSON it should be IEnumerable<HangfireTestDTO>
var arguments = JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data);

appsettings.json value not showing up in deserialized object

I have a json file with elements lined up this way:
{
"Connection":
{
"data": "...connection string..."
}
"Log":
{
"stuff": " value"
}
etc...
}
I have this model:
public class Connection
{
public string data { get; set; }
}
public class RootObject
{
public Connection Connection { get; set; }
}
and attempt to populate this way:
using (StreamReader r = new StreamReader("appsettings.json"))
{
string json = r.ReadToEnd();
var root = JsonConvert.DeserializeObject<RootObject>(json);
}
The json string gets the entire file as expected but that specific value (data) does not populate - at least I can't access it. data is null after the DeserializeObject line.
Do I need to refer to it more specifically? It's one of many values in that json file.
Your json data has one level above Connection, so you won't see it.
You need some wrapper class. var myData = JsonConvert.DeserializeObject<MyData>(stringValue);
public class MyData{
public ConnectionClass Connection {get;set;}
}
public ConnectionClass{
[JsonProperty("data")] // to keep code styling consistent
public string Data {get;set;}
}

Can't deserialize JSON into C# POCO

I can't convert JSON Object into C# class object I've tried many things but the same error pops up:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[CoderwallDotNet.Api.Models.Account]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
I am using this JSON and tring to get the response in windows 8.1 application.
[
{
"id": 1,
"time": 40,
"srcLong": 35.909124,
"srcLat": 31.973628,
"destLong": 35.898258,
"destLat": 31.985622,
"subSites": [
{
"id": 1,
"name": "location1"
},
{
"id": 2,
"name": "location2"
},
{
"id": 3,
"name": "locaion3"
}
]
}]
and the I tried to read from the JSON using webclient but its not working it can't recognize it so I am using Newtonsoft.Json and I creted these class to get the response.
public class SubSite
{
public int id { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public int time { get; set; }
public double srcLong { get; set; }
public double srcLat { get; set; }
public double destLong { get; set; }
public double destLat { get; set; }
public List<SubSite> subSites { get; set; }
}
var serviceUri = "http://localhost:24728/api/sites";
var client = new HttpClient();
var response = await client.GetAsync(serviceUri);
var datafile = await response.Content.ReadAsStringAsyn();
List<RootObject> data = JsonConvert.DeserializeObject<List<RootObject>>(datafile);
test1234.Text = data.ToString();//i am trying to for eample destlat
but I can't get the value I am getting the response and everything is fine but idk how to put it into object and use it where ever I want. For example, I want to get the value of time and the other but I have problem with List of subsites or get the location inside the subsites or srclong or srclat and here is the project how to get the Json to c# object:
https://onedrive.live.com/?cid=e648f5a0f179f346&id=E648F5A0F179F346%218429&ithint=folder,rar&authkey=!ALKlJdwsb8ER2FA
This works fine:
var data = JsonConvert.DeserializeObject<RootObject>(datafile)
You can deserialize into a dynamic object if you are not too particular about losing intellisense. One advantage to using a dynamic is that you don't have to create classes just to be able to deserialize and also that you don't need to update your class structures if the returned data has changed. As an example you can do this:
dynamic jsonValue = JsonConvert.DeserializeObject(jsonData);
foreach (dynamic rootObject in jsonValue)
{
theData.destLong.Value <-- use it anyway you want, store in a variable, etc.
// to get to each of the subSite in the rootObject
foreach (dynamic subSite in rootObject.subSites)
{
subSite.id.Value <-- returns an int based on your data
subSite.name.Value <-- returns a string based on your data
}
}
// where jsonData constains the json string you posted
The foreaeach is important because the data you posted will result into an array. You can also just do a jsonValue[0] but watch out for errors for null values, which you should be checking anyway starting with the returned json string.

write data from JSON in C#

I have JSON like this:
{
'surveys': [
{
'title': 'first',
'id': 100,
},
{
'title': 'second',
'id': 101,
},
{
'title': 'third',
'id': 102,
},
]
}
I want to have the output like this:
title: first
title: second
title: third
and my program in C# is like this:
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Example>(json);
Debug.WriteLine(example.Data.Length);
class Example
{
public surveys[] Data { get; set; }
}
class surveys
{
public string title { get; set; }
public int id { get; set; }
}
I get this error:
Thrown: "Object reference not set to an instance of an object." (System.NullReferenceException) Exception Message = "Object reference not set to an instance of an object.", Exception Type = "System.NullReferenceException", Exception WinRT Data = ""
at this line: Debug.WriteLine(example.Data.Length);
where is the problem?
One problem I see is that your outer class has a property named Data, which is an array of 'surveys' objects, but your Json has a list of 'surverys' objects under the property 'surveys'. Hence the 'Data' property is never populated.
Consider the following C# class structure:
class Example
{
public survey[] surveys{ get; set; }//Data renames to surveys
}
class survey //Singular
{
public string title { get; set; }
public int id { get; set; }
}
Why can't you do so?:
JObject data = JObject.Parse(json);
foreach (var survey in data["surveys"].Children())
{
Debug.WriteLine("title: " + survey["title"]);
}
You need to use JSON.Net and use the class JsonConvert and the method DeserializeObject<T>.
If you run this:
JsonConvert.DeserializeObject<JObject>();
Then you will get back a list of de-serialized JObject objects.
Use, NuGet to download the package. I think it is called JSON.net.
Here is the weblink
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Survey>(json);
Debug.WriteLine(example.length); // this could be count() instead.
class Survey
{
public string title { get; set; }
public int id { get; set; }
}
This should work!
Use json2csharp to generate c# classes from json.
You will also need to use Json.NET.
public class Survey
{
public string title { get; set; }
public int id { get; set; }
}
public class RootObject
{
public List<Survey> surveys { get; set; }
}
Then you can do:
var client = new WebClient();
string json = client.DownloadString(some_url);
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (Survey s in root.surveys)
{
// Do something with your survey
}
Don't forget to use Newtonsoft.Json namespace once you add a reference to it within your project.
using Newtonsoft.Json;
Edit: I have tested it using:
string json = "{'surveys': [{'title': 'first','id': 100,},{'title': 'second','id': 101,},{'title': 'third','id': 102,},]}";
instead of using the WebClient, and it works.

Parsing JSON data in C#

I have a JSON data as follows
{"id": "367501354973","from": {
"name": "Bret Taylor",
"id": "220439" }
which is returned by an object(result) of IDictionary[String, Object]
In my C# code:
I have made a class for storing the JSON value which is as follows
public class SContent
{
public string id { get; set; }
public string from_name { get; set; }
public string from_id { get; set; }
}
My main C# function which stores the parses the JSON data and stores the value inside the class properties is as follows:
List<object> data = (List<object>)result["data"];
foreach (IDictionary<string, object> content in data)
{
SContent s = new SContent();
s.id = (string)content["id"];
s.from_name = (string)content["from.name"];
s.from_id = (string)content["from.id"];
}
When i execute this code, i get an exception saying System cannot find the Key "from.name" and "from.id"
When i comment the two lines (s.from_name = (string)content["from.name"];s.from_id = (string)content["from.id"];) my code runs fine.
I think i am not able to refer the nested JSON data properly.
Can anyone just validate it and please tell me how to refer nested data in JSON in C#?
Thanks
I'm not sure how you are parsing the JSON string. Are you using a class in the Framework to do the deserialization?
You could use the JavaScriptSerializer Class defined in the System.Web.Script.Serialization Namespace (you may need to add a reference to System.Web.dll)
Using that class, you would write your code like this:
public class SContent
{
public string id { get; set; }
public SFrom from { get; set; }
}
public class SFrom
{
public string name { get; set; }
public string id { get; set; }
}
Then deserialization looks like this:
var json = new JavaScriptSerializer();
var result = json.Deserialize<SContent>(/*...json text or stream...*/);
See JavaScriptSerializer on MSDN. You might also want to check out this similar question.

Categories