{"id":"190155258007","name":"name","email":"mail#gmail.com","gender":"male",
"friends":{"data":[{"id":"1331173146","name":"friendname1"},{"id":"120497111959","name":"friendname2"},{"id":"9980211103","name":"friendname3"},
{"id":"77872075894","name":"friendname4"}]}
I am getting this JSON result but I can get deserialized value from single values but this friends array returns a null value in C#. How to fix this?
Use Newtonsoft.Json
Create your custom class:
public class MyResponse {
public string id { get; set; }
public string name { get; set; }
public string email { get; set; }
public string gender { get; set; }
public friend friends { get; set; }
public class friend{
public List<data> data {get;set;}
public class data {
string id {get;set;}
string name {get;set;}
}
}
}
Now you can deserialize your json like:
MyResponse response = Newtonsoft.Json.JsonConvert.DeserializeObject<MyResponse>("You json string here");
Now this response object will be filled by your return json string. If you don't have Newtonsoft.Json dll, you can download it from the following link:
https://www.nuget.org/packages/newtonsoft.json/
if you dont want to use custom class, you can use dynamic keyword like:
dynamic stuff = JsonConvert.DeserializeObject("Your json string here");
string name = stuff.name;
string email= stuff.email;
And so on.
Related
using Telerik.Newtonsoft.Json;
MVC Controller:
public ActionResult Index()
{
string responseStr = GetJSON();
var jObject = JsonConvert.DeserializeObject<TheViewModel>(responseStr);
if (jObject == null)
{
return Content("");
}
return View("Default", jObject);
}
Temporary hard coded JSON method:
public string GetJSON() //to be replaced after testing
{
string json = #"{
'name': 'Trial 11.7',
'id': 2599,
'version': '11.7',
'product_id': '1040',
'time_of_execution': '2017-08-07T22:15:38.000Z',
'site_url': 'http://something.com/',
'mc_gem': '11.7',
'suite_gem': '11.7',
'passing_percentage': 95.65,
'failing_percentage': 4.35
}";
return json;
}
The model:
public class TheViewModel
{
public class RootObject
{
public string name { get; set; }
public int id { get; set; }
public string version { get; set; }
public string product_id { get; set; }
public string time_of_execution { get; set; }
public string site_url { get; set; }
public string mc_gem { get; set; }
public string suite_gem { get; set; }
}
}
The problem is that I get the following as the value when I step through the code:
jObject {Master.Project.Mvc.Models.TheViewModel} Master.Project.Mvc.Models.TheViewModel
For some reason I am not getting the JSON deserialized into the object. It is probably something simple, but I am not seeing it.
I receive no error message to help determine the issue inside the controller.
Any help would be appreciated.
You're trying to convert the JSON to an object of type TheViewModel when it's looking for a type of RootObject
You can fix this by either moving all of the fields in RootObject out and into TheViewModel or by calling ...DeserializeObject<TheViewMode.RootObject>(responseStr);
Refactor your code, extract the 'RootObject' class to its own file (or move it so that it is not defined under a class.) will solve the problem.
How can we parse if json fields contains a colon(:)? Like this:
{
"dc:creator":"Jordan, Micheal",
"element:publicationName":"Applied Ergonomics",
"element:issn":"2839749823"
}
In fact I wonder how to do this with a library like restsharp, for mapping?
Using Json.Net
string json = #"{
""dc:creator"":""Jordan, Micheal"",
""element:publicationName"":""Applied Ergonomics"",
""element:issn"":""2839749823""
}";
var pub = JsonConvert.DeserializeObject<Publication>(json);
public class Publication
{
[JsonProperty("dc:creator")]
public string creator { set; get; }
[JsonProperty("element:publicationName")]
public string publicationName { set; get; }
[JsonProperty("element:issn")]
public string issn { set; get; }
}
OR
Console.WriteLine(JObject.Parse(json)["dc:creator"]);
If you use DataContractJsonSerializer, DataMemberAttribute has property Name which can be used to override default name. This means that when you deserialize json value of property dc:creator is assigned to Publication::Creator property and on the contrary when you serialize C# object.
For example:
public class Publication
{
[DataMember(Name="dc:creator")]
public string Creator { set; get; }
[DataMember(Name="element:publicationName")]
public string PublicationName { set; get; }
[DataMember(Name="element:issn")]
public string Issn { set; get; }
}
If you choose to use Json.Net, #L.B's answer is the way to go.
I want to deserialize my json object to my student class
var result = JsonConvert.DeserializeObject<Student>(data);
My json data
{
"student":{
"fname":"997544",
"lname":"997544",
"subject":"IT",
"grade":"F"
}
}
My student class
[Serializable]
public class Student
{
[JsonProperty("fname")]
public string FirstName{ get; set; }
[JsonProperty("lname")]
public string LastName{ get; set; }
[JsonProperty("subject")]
public string Subject { get; set; }
[JsonProperty("grade")]
public string Grade { get; set; }
}
The code does not work, the error says:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
Your JSON string currently represents an object with an inner object property named Student. If you want to deserialize to your Student object your JSON string should look like this:
{
"fname":"997544",
"lname":"997544",
"subject":"IT",
"grade":"F"
}
If it's not easy to change your JSON you could also use JObject to help you like so:
var jobject = JObject.Parse(jsonData);
var student = JsonConvert.DeserializeObject<Student>(jobject["student"].ToString());
Or as others have pointed out you can simply create another class wrapper and deserialize directly to that.
if you have to use your downloaded json then you need to create another model
class for it
[Serializable]
public class Student
{
[JsonProperty("fname")]
public string FirstName{ get; set; }
[JsonProperty("lname")]
public string LastName{ get; set; }
[JsonProperty("subject")]
public string Subject { get; set; }
[JsonProperty("grade")]
public string Grade { get; set; }
}
[Serializable]
public class NewModel
{
public Student Student { get; set; }
}
then deserialize
var result = JsonConvert.DeserializeObject<NewModel>(data);
You JSON object is inside a nameless Root / Parent Object.
So Use something like the following.
var result = JsonConvert.DeserializeObject<RootObject>(data);
then your Student instance can be access as result.student
Ex:
string firstName = result.student.FirstName;
I use Json2CSharp to generate the additional RootObject class.
Here's all the class definitions
[Serializable]
public class Student
{
[JsonProperty("fname")]
public string FirstName{ get; set; }
[JsonProperty("lname")]
public string LastName{ get; set; }
[JsonProperty("subject")]
public string Subject { get; set; }
[JsonProperty("grade")]
public string Grade { get; set; }
}
[Serializable]
public class RootObject
{
public Student student { get; set; }
}
Because you're trying to deal with the object from JSON, it's easiest to start with
var jStudent = JObject.Parse(jsonData);
You can then go to any sub property of the JObject through key reference and deserialize as you're expecting.
var student = JsonConvert.DeserializeObject<Student>(jStudent["student"].ToString());
Hope that helps
Since you cannot change your Json string, you need to modify your class structure to match it. Note that the student object is wrapped in another class. The class structure to use this Json data looks like this:
public class Wrapper
{
public Student Student { get; set; }
}
public class Student
{
[JsonProperty("fname")]
public string FirstName { get; set; }
[JsonProperty("lname")]
public string LastName { get; set; }
[JsonProperty("subject")]
public string Subject { get; set; }
[JsonProperty("grade")]
public string Grade { get; set; }
}
And deserialise like this:
var wrapper = JsonConvert.DeserializeObject<Wrapper>(data);
I call a Weather API - which returns Json response.
My C# Code-
Uri uri1 = new Uri(APIUrl);
WebRequest webRequest1 = WebRequest.Create(uri1);
WebResponse response1 = webRequest1.GetResponse();
StreamReader streamReader1 = new StreamReader(response1.GetResponseStream());
String responseData1 = streamReader1.ReadToEnd().ToString();
dynamic data1 = JObject.Parse(responseData1 )
I get Exception while calling Parse as below-
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException' occurred in Newtonsoft.Json.dll
Additional information: Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
My Analysis-
responseData1 has json strings as-
responseData1="[{\"locationName\":\"Bangalore\",\"subLocationName\":null,\"gid\":\"43295\",\"subStateID\":null,\"subStateName\":null,\"stateID\":\"II\",\"stateName\":\"Indien\",\"latitude\":12.9667,\"longitude\":77.5833,\"altitude\":900,\"zip\":null}\n, {\"match\":\"yes\"}]"
If i check this json in http://jsonlint.com/ - It says valid json.
If i hit my APIUrl directly in browser-
repose in browser is as below-
[{"locationName":"Bangalore","subLocationName":null,"gid":"43295","subStateID":null,"subStateName":null,"stateID":"II","stateName":"Indien","latitude":12.9667,"longitude":77.5833,"altitude":900,"zip":null}, {"match":"yes"}]
My aim is to read the value of property "gid" from the above json.
Can someone help me here?
Thanks!
You're using the JObject class, when you should be using the JArray class, because the JSON you're attempting to parse is an array - not an object:
http://www.newtonsoft.com/json/help/html/ParseJsonArray.htm
It would be better to create a model for this. Then you can simply tell Newtonsoft to deserialize the JSON string instead of using a dynamic type.
First, you would need to create a model like this:
public class WeatherData
{
public string locationName { get; set; }
public string subLocationName { get; set; }
public string gid { get; set; }
public int subStateID { get; set; }
public string subStateName { get; set; }
public string stateID { get; set; }
public string stateName { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public int altitude { get; set; }
public string zip { get; set; }
public string match { get; set; }
}
Then deserialize the return JSON as follows:
var data1 = JsonConvert.DeserializeObject<WeatherData>(responseData1);
Or for an array:
var data1 = JsonConvert.DeserializeObject<List<WeatherData>>(responseData1);
I am getting JSON that is being returned from a REST web service for survey responses. It has arrays for the name portion of some of the name value pairs. Additionally the names will be variable depending on the type of questions asked. I'm using JSON.net and trying to deserialize the returned value into some type of object tree that I can walk but can't figure out what structure to use to have it filled in.
I tested the following snippet in LinqPad and fields is always empty. Is there someway to easily read in the variable data or do I have to parse it in code?
void Main() {
string json = #"{
'result_ok':true,
'total_count':'51',
'data':[{
'id':'1',
'status':'Deleted',
'datesubmitted':'2015-01-12 10:43:47',
'[question(3)]':'Red',
'[question(4)]':'Blue',
'[question(18)]':12,
'[variable(\'STANDARD_IP\')]':'127.0.0.1',
'[variable(\'STANDARD_GEOCOUNTRY\')]':'United States'
}]
}";
var responses = JsonConvert.DeserializeObject<RootObject>(json);
responses.Dump();
}
public class RootObject {
public bool result_ok { get; set; }
public string total_count { get; set; }
public List<Response> data { get; set; }
}
public class Response {
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
public List<object> fields = new List<object>();
}
Change the fields property in your Response class to be a Dictionary<string, object>, then mark it with a [JsonExtensionData] attribute like this:
public class Response
{
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
[JsonExtensionData]
public Dictionary<string, object> fields { get; set; }
}
All of the fields with the strange property names will then be placed into the dictionary where you can access them as normal. No extra code is required.
Here is a demo: https://dotnetfiddle.net/1rQUXT