I'm using the Newtonsoft JSON parser in C#. The JSON seems to be formatted correctly but I'm getting a read error that doesn't make sense. The JSON should deserialize and load into the class instance automatically.
Class:
class FilterMatrix {
public int ID { get; set; }
public int ParentID { get; set; }
}
Deserializing code:
string fileName = #"C:\Users\accounts.json";
FilterMatrix kernel = JsonConvert.DeserializeObject<FilterMatrix>(File.ReadAllText(fileName));
JSON file contents:
{"Features":[{"ID":0,"ParentID":0},{"ID":0,"ParentID":0}]}
Error:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path 'Features', line 1, position 14.'
Well, at least the structure of the JSON needs to match your class hierarchy. Working example:
class Program
{
static void Main(string[] args)
{
var root = JsonConvert.DeserializeObject<Root>(File.ReadAllText("file.json"));
}
}
public class Root
{
public List<FilterMatrix> Features { get; set; }
}
public class FilterMatrix
{
public int ID { get; set; }
public int ParentID { get; set; }
}
Thanks, Gene.
I basically came up with this as I saw your post. It never donned on me to have multiple classes within a class. I guess I assumed an array of classes would be automatically made :-/
JSON script:
{"Features":[{"ID":0,"ParentID":0},{"ID":0,"ParentID":0}]}
Deserialization:
kernel = JsonConvert.DeserializeObject<FilterMatrix>(File.ReadAllText(fileName));
My classes:
class FilterMatrix {
private List<Feature> features = new List<Feature>();
public List<Feature> FeaturesList
{
get { return features; }
set { features = value; }
}
}
class Feature {
public int ID { get; set; }
public int ParentID { get; set; }
}
I access elements by their index:
kernel.FeaturesList[0].ID
Related
Using the method JsonConvert.DeserializeObject returns the default values for all properties.
var current = JsonConvert.DeserializeObject<Current>(myJson);
{
"location": {
"name": "London"
},
"current": {
"temp_c": 5.0,
"cloud": 50
}
}
public class Current
{
public double Temp_c { get; set; }
public double Cloud { get; set; }
}
The expected current object should have the values: 50 for Cloud, and 5.0 for Temp_c, but returns the default values for all properties.
You need to define a class model like json object
and then deserialize to it
public class YourModel {
//create location class that has Name property
public Location Location { get; set; }
//create current class that has Temp_c and Cloud property
public Current Current { get; set; }
}
and then
var data = JsonConvert.DeserializeObject<YourModel>(myJson);
and get the current value from data object
var current = data.Current;
your 'Current' class is far of been like the JSON you post.
You need to convert the JSON string to a C# class. You can use QuickType to convert it (Newtonsoft compatible).
Note: I am using System.Text.Json.Serialization but the class model should be equal, just change:
[JsonPropertyName("temp_c")] // .Net serializer (I prefer this)
to
[JsonProperty("temp_c")] // Newtonsoft.Json serializer
(replace "temp_c" for every name)
Here is the class model (a complete console application) you need:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
#nullable disable
namespace test
{
public class Weather
{
[JsonPropertyName("location")]
public Location Location { get; set; }
[JsonPropertyName("current")]
public Current Current { get; set; }
}
public class Location
{
[JsonPropertyName("name")]
public string Name { get; set; }
}
public class Current
{
[JsonPropertyName("temp_c")]
public double TempC { get; set; }
[JsonPropertyName("cloud")]
public int Cloud { get; set; }
}
class Program
{
static void Main(string[] args)
{
string json = "{\"location\": { \"name\": \"London\" }, \"current\": { \"temp_c\": 5.0, \"cloud\": 50 }}";
Weather myWeather = JsonSerializer.Deserialize<Weather>(json);
Console.WriteLine("Location: {0} - Temp: {1:F}", myWeather.Location.Name, myWeather.Current.TempC);
}
}
}
Now the Deserializer will work OK.
I need a little assistance in obtaining values from a JSON object in C#. Here is the code and the output. I am trying to retrieve value of ScoreRepresentation from both the objects. The obtained values in this case would be BR400L and null as per the below output.
Can anyone please assist? Newbie in C# :) Thanks in advance
using System;
using Microsoft.VisualBasic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
var json = "{\"Results\":[{\"RequestIdentifier\":\"Lexile\",\"ValueType\":\"INTEGER\",\"Scores\":[{\"lexile\":{\"ScoreValue\":-400,\"ScaledScore\":-400,\"ScoreRepresentation\":\"BR400L\"}}]},{\"RequestIdentifier\":\"UnifiedScaleScore\",\"ValueType\":\"INTEGER\",\"Scores\":[{\"unifiedScaleScore\":{\"ScoreValue\":610,\"ScaledScore\":610,\"ScoreRepresentation\":null}}]}]}";
var deserialized = JsonConvert.DeserializeObject(json);
Console.WriteLine(deserialized);
}
}
}
Output:
{
"Results": [
{
"RequestIdentifier": "Lexile",
"ValueType": "INTEGER",
"Scores": [
{
"lexile": {
"ScoreValue": -400,
"ScaledScore": -400,
"ScoreRepresentation": "BR400L"
}
}
]
},
{
"RequestIdentifier": "UnifiedScaleScore",
"ValueType": "INTEGER",
"Scores": [
{
"unifiedScaleScore": {
"ScoreValue": 610,
"ScaledScore": 610,
"ScoreRepresentation": null
}
}
]
}
]
}
I like to go the "Model" route. You create models of your data, then you can easily deserialize to them. Sometimes when I am feeling lazy, I will use this site to do my work for me.
So, for your specific example, it gives back these models:
public class Lexile {
public int ScoreValue { get; set; }
public int ScaledScore { get; set; }
public string ScoreRepresentation { get; set; }
}
public class UnifiedScaleScore {
public int ScoreValue { get; set; }
public int ScaledScore { get; set; }
public object ScoreRepresentation { get; set; }
}
public class Score {
public Lexile lexile { get; set; }
public UnifiedScaleScore unifiedScaleScore { get; set; }
}
public class Result {
public string RequestIdentifier { get; set; }
public string ValueType { get; set; }
public List<Score> Scores { get; set; }
}
public class Root {
public List<Result> Results { get; set; }
}
Then, you can simply deserialize to Root by doing this:
var deserialized = JsonConvert.DeserializeObject<Root>(json);
Keep in mind that if your JSON is not perfect, you will find some inconsistencies with the output. You may have to massage your models a bit to fix those issues. You can't just assume that site gives you 100% accurate data.
But, if it's good enough, you can now get at every property you'd ever need to without having to putz around with dynamics or JToken.
For example:
foreach(var r in deserialized.Results)
{
foreach(var s in r.Scores)
{
Console.Write(s.unifiedScaleScore.ScoreRepresentation);
}
}
I want to bind json obect to my properties When I deserialize the json object and bind into the properties ,properties shows null values,please some one help me to resolve this.
this is my code
string s = "{\"response\":{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}}";
var jsonObj = JObject.Parse(s);
response myDeserializedObj = (response)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonObj.ToString(), typeof(response));
this is properties
public class response
{
public string status { get; set; }
public content content { get; set; }
}
public class content
{
public string user_id { get; set; }
public string first { get; set; }
public string last { get; set; }
public string username { set; get; }
}
Thanks,
karthik
I copied you code and tested it in my machine and I could solve your problem
here is the solution
add the following class
public class ResponseWrapper
{
public response response { get; set; }
}
replace your code with the following
string s = "{\"response\":{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}}";
response my = JsonConvert.DeserializeObject<ResponseWrapper>(s).response;
I am sure this will work.
UPDATE
Another solution (Which is tested also) and better than the first one
because it is more clean, and in this way you have not to create new wrapper class.
the solution is replace your string with the following string.
and all of your previous code will stay the same
here is the correct JSON string
string s = "{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}";
UPDATE 2
in the comments below of this answer you asked a completely a new question.
here is your new question (I copied this from your comments)
public class responseWraper
{
public response response { get; set; }
}
public class response
{
public string status { get; set; }
public content content { get; set; }
}
public class content
{
public Employees Employees { get; set; }
}
public class Employees
{
public string Employee_id { get; set; }
public string Employee_name { get; set; }
public string status { get; set; }
}
and here is how you are trying to deserialize this (also this copied from your comments)
string s = "{\"response\":{\"status\":\"success\",\"content\":{\"Employees\":[{\"Employee_id\":\"1\",\"Employee_name\":\"Sravan\",\"status\":\"1\"},}]}}}";
response my = Newtonsoft.Json.JsonConvert.DeserializeObject<responseWraper>(s).response;
ANSWER
your code has two problem
the first is you are using the Employees as array in the JSON string, but the type of the Employees property is not an array
the second problem that the JSON string itself is not valid. it has an errors
there is 4 { character but you have 5 } character inside it.
so you have to fix those two problem as the following
public class content
{
public List<Employees> Employees { get; set; }
}
and the string is
string s = "{\"response\":{\"status\":\"success\",\"content\":{\"Employees\":[{\"Employee_id\":\"1\",\"Employee_name\":\"Sravan\",\"status\":\"1\"},]}}}";
and if you have any other question , I will be happy to help you :)
Try your JSON with http://json2csharp.com/.
Your current code would deserialize the following JSON:
{
"status":"fail",
"content":{
"user_id":"56",
"first":"kiran",
"last":"kumar",
"username":"kirankumar"
},
"msg":"shggh"
}
You are missing a root class with a single Property "response" with the type "Response"
I've been trying to parse this JSON string. I'm using JSON.NET and a snippet of the JSON, my classes and basic function calls follow:
{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}
The classes I'm using as storage objects:
public class Folks
{
public Folks()
{
}
public String status;
public String message; //optional
public int apirate;
public PeopleDetails[] people;
}
public class PeopleDetails
{
public PeopleDetails ()
{
}
public String id;
public double rating;
public int questions;
}
And finally, what I'm doing in the code:
Folks test = new Folks();
test = JsonConvert.DeserializeObject<Folks>(myRequest.GetResponse());
Status and API rate are coming through fine, message doesn't exist because there's no error and my PeopleDetails array is making an exception. (EDIT: throwing a JsonSerializationException because the type requires a JSON array to deserialize correctly.) I've tried putting another class/object between the two I've pasted here and I've tried different collections, and so on.
So... since this is my first time working with this (smart, pick the complex stuff the first time) can anybody point me towards a solution?
Thanks in advance.
Well, first, your given JSON is incorrect, there is a { missing in the penelope record.
so the correct JSON would be
{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}
Then, if you have a look at the structur, you may not that people is not a list but a dictionary, with the name as the key.
So, here is a working test
[TestMethod]
public void Test()
{
var json = "{\"status\":\"ok\",\"apirate\":\"0\",\"people\":{\n\"Mike\":{\"id\":\"Mike\",\"rating\":\"0.80\",\"questions\":\"100\"},\n\"Donald\":{\"id\":\"Donald\",\"rating\":\"0.7\",\"questions\":\"9\"},\n\"Tony\":{\"id\":\"Tony\",\"rating\":\"0.22\",\"questions\":\"2\"},\n\"Penelope\":{\"id\":\"Penelope\",\"rating\":\"0.006\",\"questions\":\"6\"},\n\"Sarah\":{\"id\":\"Sarah\",\"rating\":\"0.79\",\"questions\":\"20\"},\n\"Thomas\":{\"id\":\"Thomas\",\"rating\":\"0.12\",\"questions\":\"25\"},\n\"Gail\":{\"id\":\"Gail\",\"rating\":\"0.44\",\"questions\":\"35\"}}}";
var folks = JsonConvert.DeserializeObject<Folks>(json);
Assert.AreEqual("ok", folks.Status);
}
public class Folks
{
public Folks()
{
this.People = new Dictionary<string, PeopleDetails>();
}
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("apirate")]
public int Apirate { get; set; }
[JsonProperty("people")]
public Dictionary<string, PeopleDetails> People { get; set; }
}
public class PeopleDetails
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("rating")]
public decimal Rating { get; set; }
[JsonProperty("questions")]
public int Questions { get; set; }
}
I am currently developing a client library for connecting to Newegg using the documentation provided by Newegg and have a question on class design.
In working with various API's ( namely NetSuite and Amazon's MWS ) I come across classes that have are used like this:
recToFulfill.packageList = new ItemFulfillmentPackageList();
recToFulfill.packageList.package = new ItemFulfillmentPackage[ifitemlist.item.Length];
recToFulfill.packageList.package[i] = new ItemFulfillmentPackage();
recToFulfill.packageList.package[i].packageWeightSpecified = true;
recToFulfill.packageList.package[i].packageTrackingNumber = "trackingNumber";
The question I have is: How do I properly design the nested objects like above? I have never had to worry about this previously, so I am unsure on where to look, or start.
The bit I need to figure out looks like this ( taken from the API documentation provided):
<UpdateOrderStatusInfo>
<IsSuccess></IsSuccess>
<Result>
<OrderNumber></OrderNumber>
<SellerID></SellerID>
<OrderStatus></OrderStatus>
</Result>
</UpdateOrderStatusInfo>
All fields are type string, except order number which is an integer.
I have this currently:
public class UpdateOrderStatusInfo
{
public string IsSuccess { get; set; }
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
But the returned XML Response has Results as a parent node which to me seems like it should be represented within the class itself. Would I just do this?
public UpdateOrderStatusInfo results {get; set;}
If so, where do the child nodes go?
What I need is to be able to say is something like:
UpdateOrderStatusInfo updateInfo = new UpdateOrderStatusInfo();
if(updateInfo.IsSuccess.Equals("true")
{
Console.WriteLine(updateInfo.Results.OrderStatus);
}
Any help, or advice on where to get this information is appreciated.
Easy breezy. If it has no children, it's a scalar property. If it does, it is its own class, and referenced in the parent class accordingly. If it repeats, it's a collection, and is referenced like a class (these are complex type, not primitives). Make sure you initialize them in your constructors).
class Program
{
static void Main(string[] args)
{
var myOrder = new UpdateOrderStatusInfo();
myOrder.IsSuccess = "true";
myOrder.OrderResult.OrderNumber = 1001;
myOrder.OrderResult.OrderStatus = "Pending";
myOrder.OrderResult.SellerID = "69";
}
}
public class UpdateOrderStatusInfo
{
public string IsSuccess { get; set; }
public Result OrderResult { get; set; }
public UpdateOrderStatusInfo()
{
OrderResult = new Result();
}
}
public class Result
{
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
You need to define the Result as a separate class, called whatever you want, then add a Result property as that type. The Result class can be defined at the namespace level, or, if you are unlikely to use it anywhere else on its own, you can nest the class definition inside the UpdateOrderStatusInfo class:
public class UpdateOrderStatusInfo
{
public class UpdateOrderResult
{
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
public UpdateOrderStatusInfo()
{
Result = new UpdateOrderResult();
}
public string IsSuccess { get; set; }
public UpdateOrderResult Result { get; set; }
}
The easy way is to use the xsd.exe tool.
The command xsd response.xml will generate the file response.xsd
The command xsd response.xsd /C will generate the file response.cs which contains the classes necessary to serialize/deserialize the xml posted.