Custom C# object from JSON - c#

I get the following JSON response.
[
{
"Issue": {
"ID": 80,
"Name": "Cold",
"Accuracy": 90,
"Icd": "J00",
"IcdName": "Acute nasopharyngitis [common cold]",
"ProfName": "Common cold",
"Ranking": 1
},
"Specialisation": [
{
"ID": 15,
"Name": "General practice",
"SpecialistID": 0
}
]
}
]
I tried to follow the instructions given here. But I can't seem to fit that solution here. And in the documentation is explained only the scenario where you already have the class predefined. Any help?

Presumptions
Your question is not even clear. What are you asking? I presume you are asking how to make a C# class from that JSON?
Solution
Firstly, the JSON is an array (if its top-level tags are [] its an array itself. If its top level is {} then its a single object.
So what you have is an array returned with one result inside of it.
Going to json2csharp and pasting your code gives this:
public class Issue
{
public int ID { get; set; }
public string Name { get; set; }
public int Accuracy { get; set; }
public string Icd { get; set; }
public string IcdName { get; set; }
public string ProfName { get; set; }
public int Ranking { get; set; }
}
public class Specialisation
{
public int ID { get; set; }
public string Name { get; set; }
public int SpecialistID { get; set; }
}
public class RootObject
{
public Issue Issue { get; set; }
public List<Specialisation> Specialisation { get; set; }
}
And you can see its created a RootObject almost indicating it is a single object, but you will need to deserialize this as a List<RootObject> not just RootObject.
So in C# that would be var result = JsonConvert.DeserializeObject<List<RootObject>>(theJsonString);

You should have a strongly typed c# class ready for your Json Response to be deserialized into... Json Utils has a generator to use, it came up with this:
public class Issue
{
[JsonProperty("ID")]
public int ID { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Accuracy")]
public int Accuracy { get; set; }
[JsonProperty("Icd")]
public string Icd { get; set; }
[JsonProperty("IcdName")]
public string IcdName { get; set; }
[JsonProperty("ProfName")]
public string ProfName { get; set; }
[JsonProperty("Ranking")]
public int Ranking { get; set; }
}
public class Specialisation
{
[JsonProperty("ID")]
public int ID { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("SpecialistID")]
public int SpecialistID { get; set; }
}
public class RootObject
{
[JsonProperty("Issue")]
public Issue Issue { get; set; }
[JsonProperty("Specialisation")]
public IList<Specialisation> Specialisation { get; set; }
}
Then use
RootObject jsonAsCSharpClass = JsonConvert.DeserializeObject<RootObject>(jsonResponse);
I'm not 100% sure this class is good for you though, i have never some across a response where the root response is an array, without defining a root property first, see how it starts with "[" instead of { ??? You may want to also try
List<RootObject> jsonAsCSharpClass = JsonConvert.DeserializeObject<List<RootObject>>(jsonResponse);
Or wait for someone with more knowledge on the subject to come along...

Related

C# WebApi POST creating a objects with complex json data

I have two models, a SettingCollection, and a SettingValue. A SettingCollection has many SettingValues. This is the setup of this relationship.
public class SettingCollection
{
public int SettingCollectionId { get; set; }
public string Name { get; set; }
public string Key { get; set; }
public int Priority { get; set; }
public ICollection<SettingValue> SettingValues {get; set; }
}
and
public class SettingValue
{
public int SettingValueId { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public int SettingCollectionId { get; set; }
public SettingCollection SettingCollection { get; set; }
}
To create a new SettingCollection and SettingValues in one call, I am POSTing the following payload:
{
"Name": "Company Collection",
"Key": "company_collection",
"Priority": 3,
"SettingValues":
[{"Name": "Is this true", "Value": "True"}]
}
And my response is:
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
Is this just something I cannot do and will have to use NewtonSoft to suss out the raw data in the controller?
Thanks!
Add this options to your newtonsoft.json in your startup file
AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
options.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
})
These classes are self referenced, so they go into the loop. You can just ignore sub classes with JsonIgnoreAttribute. I used this with System.Text.Json.JsonSerializer and works fine.
public class SettingValue
{
public int SettingValueId { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public int SettingCollectionId { get; set; }
[JsonIgnore]
public SettingCollection SettingCollection { get; set; }
}

C# Parsing JSON String

I have tried countless methods to Parse my JSON string (Steam Public Data), yet nothing seems to work. I just want to be able to extract values from the string. For Example, obtaining the value of personaname which would return SlothGod. I have JSON.NET installed in my project.
Here is my JSON:
{
"response": {
"players": [
{
"steamid": "76561198301407459",
"communityvisibilitystate": 3,
"profilestate": 1,
"personaname": "SlothGod",
"lastlogoff": 1508389707,
"commentpermission": 1,
"profileurl": "http://steamcommunity.com/id/sleuthgud/",
"avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba.jpg",
"avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_medium.jpg",
"avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_full.jpg",
"personastate": 0,
"realname": "Josh",
"primaryclanid": "103582791460168790",
"timecreated": 1462086929,
"personastateflags": 0,
"loccountrycode": "AU",
"locstatecode": "QLD"
}
]
}
}
Main method suggested to me:
public class Details
{
public string personaname { get; set; }
}
private void GetSteamDetails()
{
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Details>(SteamDetailsJson);
SteamName = data.personaname;
}
This is placed before Page_Load(). I then call GetSteamDetails(); when I want to fetch the name.
After my question being down voted, I decided to not give up on this problem. After extensive research, trial and error, and YouTube tutorials which are the most helpful IMO. I found that the data was containing a JSON array, and yes I will admit, I was confused with this, but the answer was to simply treat it like a C# array and add [1] to the end of players.
Details details = new Details();
public class Details
{
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public string realname { get; set; }
public string personaname { get; set; }
public string steamid { get; set; }
}
private void GetSteamDetails()
{
var SteamDetails= JsonConvert.DeserializeObject<dynamic>(SteamDetailsJson);
avatar = SteamDetails.response.players[1].avatar.ToString();
personaname = SteamDetails.response.players[1].personaname.ToString();
}
Based on the JSON string you provided, you should have the following C# classes to support it, or to deserialize the JSON object values into: I used this link to generate the classes.
public class Player
{
public string steamid { get; set; }
public int communityvisibilitystate { get; set; }
public int profilestate { get; set; }
public string personaname { get; set; }
public int lastlogoff { get; set; }
public int commentpermission { get; set; }
public string profileurl { get; set; }
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public int personastate { get; set; }
public string realname { get; set; }
public string primaryclanid { get; set; }
public int timecreated { get; set; }
public int personastateflags { get; set; }
public string loccountrycode { get; set; }
public string locstatecode { get; set; }
}
public class Response
{
public List<Player> players { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}
Then, using Newtonsoft.Json, you can deserialize the JSON object into your C# classes as follow:
JsonConvert.DeserializeObject<RootObject>("yourJsonString");
You mention that Newtonsoft.Json already referenced in the project.
Use class to represent json data structure, then you can easy deserialize it.
You can use only properties you need in the class.
public class Player
{
public string personaname { get; set; }
}
var player = Newtonsoft.Json.JsonConvert.DeserializeObject<Player>(jsonString);
// use player.personaname
For updates question create classes which represent your data structure
public class Team
{
public List<Player> players { get; set; }
}
public class Response
{
public Team response { get; set; }
}
You can use http://json2csharp.com/ to generate a class automatically from a JSON string.

How to deserialize json into collection of Objects

I have the following JSON (I can't change the incoming JSON as it is from a 3rd party system):
{
"id": 23,
"userName":"test#test.com",
"tags":
{
"Employee ID":
{
"name":"Employee ID",
"value":"123456789"
},
"Job Family":
{
"name": "Job Family",
"value": "Accounting and Finance"
}
}
}
First, I tried to deserialize using this class structure:
public class User
{
[JsonProperty("id")]
public int ID { get; set; }
[JsonProperty("username")]
public string Email { get; set; }
[JsonProperty("tags")]
public TagsJson Tags { get; set; }
}
public class TagsJson
{
[JsonProperty("tags")]
public List<Tag> Tags { get; set; }
}
public class Tag
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
In using Newtonsoft's JsonConvert.DeserializeObject(json);, the User.Tags property is always empty. This is obviously because there are no "Tags" under the "Tags" attribute.
Yet, if I change the User class as follows...
public class User
{
[JsonProperty("id")]
public int ID { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("tags")]
public List<Tag> Tags { get; set; }
// I even tried Tag[] instead of List<Tag> here
}
...I get the following error:
Additional information: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[Tag]' because the type requires
a JSON array (e.g. [1,2,3]) to deserialize correctly.
Any suggestions on creating the User class to allow it to deserialize correctly would be greatly appreciated.
EDIT
So this may or may not be the best answer, but it works. The tags coming in will be one of a dozen different names. So I created a Tags class with a property for each of the 12 possibilites. Since none are required, any of them that do appear will get populated. Here's my adjusted User, Tags (formerly TagsJson) and Tag classes below - but I'm definitely interested in a better solution.
public class User
{
[JsonProperty("id")]
public int ID { get; set; }
[JsonProperty("username")]
public string Email { get; set; }
[JsonProperty("tags")]
public Tags AllTags { get; set; }
}
public class Tags
{
[JsonProperty("Employee ID")]
public Tag EmployeeID { get; set; }
[JsonProperty("Job Family")]
public Tag JobFamily { get; set; }
// ... and 10 more properties for additional tags that may appear but are not required
}
public class Tag
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
The suggested answer of this question does not work in my case because the JSON is not an array or a collection but a list of unique attribute names with a name/value pairing.
Well using the Visual Studio paste Json as classes yields...
public class Rootobject
{
public int id { get; set; }
public string userName { get; set; }
public Tags tags { get; set; }
}
public class Tags
{
[JsonProperty(PropertyName = "Employee ID")]
public EmployeeID EmployeeID { get; set; }
[JsonProperty(PropertyName = "Job Family")]
public JobFamily JobFamily { get; set; }
}
public class EmployeeID
{
public string name { get; set; }
public string value { get; set; }
}
public class JobFamily
{
public string name { get; set; }
public string value { get; set; }
}
I had to add in the JsonProperty attributes myself. However I think a better solution would be...
public class Rootobject2
{
public int id { get; set; }
public string userName { get; set; }
public IDictionary<string, NameValuePair> tags { get; set; }
}
public class NameValuePair
{
public string name { get; set; }
public string value { get; set; }
}
Although the paste Json as classes was a good starting point to easily copy and paste the code into the favoured solution.
Some test code...
string json = Resource1.String1;
Rootobject test = JsonConvert.DeserializeObject<Rootobject>(json);
Rootobject2 test2 = JsonConvert.DeserializeObject<Rootobject2>(json);
Not sure your JSON is correct but why is there space in your property name Employee ID or Job Family. Fix those in Tags class and we are good to go.
public class EmployeeID
{
public string name { get; set; }
public string value { get; set; }
}
public class JobFamily
{
public string name { get; set; }
public string value { get; set; }
}
public class Tags
{
public EmployeeID __invalid_name__Employee ID { get; set; }
public JobFamily __invalid_name__Job Family { get; set; }
}
public class User
{
public int id { get; set; }
public string userName { get; set; }
public Tags tags { get; set; }
}
This is what i got from json2csharp.com
Your JSON shows that your tags object is an Object - not an Array. You cannot deserialize an Object into a C# List because they are different structures.
If the keys in tags are dynamic/changing, then perhaps try
[JsonProperty("tags")]
Dictionary<string, string> Tags { get; set; }
Edit
It appears that your JSON is not well-formed; if you aren't able to modify it, you might have to use a custom JsonConverter.

processing api output in vb.net or c#

After making an api call, the example below shows what a typical response would be.
{
"code":"success",
"message":"Data retrieved for email",
"data":{
"attributes":{
"EMAIL":"example#example.net",
"NAME" : "Name",
"SURNAME" : "surname"
},
"blacklisted":1,
"email":"example#example.net",
"entered":"2014-01-15",
"listid":[8],
"message_sent":[{
"camp_id" : 2,
"event_time" : "2013-12-18"
},
{ "camp_id" : 8,
"event_time" : "2014-01-03"
},
{ "camp_id" : 11,
"event_time" : "2014-01-07"
}],
"hard_bounces":[{
"camp_id" : 11,
"event_time" : "2014-01-07"
}],
"soft_bounces":[],
"spam":[{
"camp_id" : 2,
"event_time" : "2014-01-09"
}],
"unsubscription":{
"user_unsubscribe":[
{
"event_time":"2014-02-06",
"camp_id":2,
"ip":"1.2.3.4"
},
{
"event_time":"2014-03-06",
"camp_id":8,
"ip":"1.2.3.4"
}
],
"admin_unsubscribe":[
{
"event_time":"2014-04-06",
"ip":"5.6.7.8"
},
{
"event_time":"2014-04-16",
"ip":"5.6.7.8"
}
]
},
"opened":[{
"camp_id" : 8,
"event_time" : "2014-01-03",
"ip" : "1.2.3.4"
}],
"clicks":[],
"transactional_attributes":[
{
"ORDER_DATE":"2015-07-01",
"ORDER_PRICE":100000,
"ORDER_ID":"1"
},
{
"ORDER_DATE":"2015-07-05",
"ORDER_PRICE":500000,
"ORDER_ID":"2"
}
],
"blacklisted_sms":1
}
}
What I need to do is to be able to read / find and attribute name and its corresponding value. I also need to know the value of blacklisted.
I don't know how to interpret the output given to easily find and read attributes and their values and also get the value of blacklisted.
Maybe if I can get it into an array, I can cycle through the array to find the value pair I am looking for? Or maybe I am overthinking it and their is an easier way.
Please note: This example only shows 3 attribute:value pairs. other calls may output more than three attribute:value pairs.
The simplest way is: You are getting the response in the JSON format and you just need it to be seralized with the use of classes and Json.NET
public class Rootobject
{
public string code { get; set; }
public string message { get; set; }
public Data data { get; set; }
}
public class Data
{
public Attributes attributes { get; set; }
public int blacklisted { get; set; }
public string email { get; set; }
public string entered { get; set; }
public int[] listid { get; set; }
public Message_Sent[] message_sent { get; set; }
public Hard_Bounces[] hard_bounces { get; set; }
public object[] soft_bounces { get; set; }
public Spam[] spam { get; set; }
public Unsubscription unsubscription { get; set; }
public Opened[] opened { get; set; }
public object[] clicks { get; set; }
public Transactional_Attributes[] transactional_attributes { get; set; }
public int blacklisted_sms { get; set; }
}
public class Attributes
{
public string EMAIL { get; set; }
public string NAME { get; set; }
public string SURNAME { get; set; }
}
public class Unsubscription
{
public User_Unsubscribe[] user_unsubscribe { get; set; }
public Admin_Unsubscribe[] admin_unsubscribe { get; set; }
}
public class User_Unsubscribe
{
public string event_time { get; set; }
public int camp_id { get; set; }
public string ip { get; set; }
}
public class Admin_Unsubscribe
{
public string event_time { get; set; }
public string ip { get; set; }
}
public class Message_Sent
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Hard_Bounces
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Spam
{
public int camp_id { get; set; }
public string event_time { get; set; }
}
public class Opened
{
public int camp_id { get; set; }
public string event_time { get; set; }
public string ip { get; set; }
}
public class Transactional_Attributes
{
public string ORDER_DATE { get; set; }
public int ORDER_PRICE { get; set; }
public string ORDER_ID { get; set; }
}
Use Newtonsoft.Json library. One of the most powerful library.Parse your JSON to strongly typed C# object using json2csharp.com then just deserialize the string.
var model= JsonConvert.DeserializeObject<Classname>(result);
You'll need JSON.Net. Pasrse your JSON to strongly typed C# object using json2csharp.com then just deserialize the string using JsonConvert.Deserialize<RootObject>().
One way would be to:
a) Copy your JSON to Clipboard (CTRL+C)
b) On a Visual Studio class, click on EDIT-> Paste Special -> Paste JSON as classes. This will create the classes equivalent of your JSON for you. Your main object would be named as "Rootobject" and you can change this to whatever name you want.
c) Add System.Web.Extensions to your references
d) You can convert your JSON to class like so:
JavaScriptSerializer serializer = new JavaScriptSerializer();
Rootobject rootObject = serializer.Deserialize<Rootobject>(JsonString);
Where JsonString is your API output.

Error while deserializing the JSON

I'm getting the JSON output as follows:
{"data":
[
{
"name":"followersQuery",
"fql_result_set":[{"subscriber_count":300}]
},
{
"name":"likesQuery",
"fql_result_set":[{"like_count":0}]
}
]
}
It is the output of multiple fql query.
I have created the following classes to deserialize the output:
public class ResultCount
{
[JsonProperty("subscriber_count")]
public int Followers { get; set; }
[JsonProperty("like_count")]
public int Likes { get; set; }
}
public class ResultItem
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("fql_result_set")]
public ResultCount ResultCounts { get; set; }
}
public class FacebookData
{
public List<ResultItem> Items { get; set; }
}
I'm getting error while de-serializing the output in the following line:
JsonConvert.DeserializeObject<FacebookData>(myOutput);
The error is:
The best overloaded method match for
'Newtonsoft.Json.JsonConvert.DeserializeObject(string)'
has some invalid arguments.
Not able to correct this. Can anyone please correct this?
Many many thanks in advance!
ResultCounts return type should be List<Resultcount>.
Change
public ResultCount ResultCounts { get; set; }
to
public List<ResultCount> ResultCounts { get; set; }
On a sidenote you can get class structue by simply pasting your json here - Json2csharp. It will automatically generate class structure for you. It can be use to validate your structure. Generated structure was like this:
public class FqlResultSet
{
public int subscriber_count { get; set; }
public int? like_count { get; set; }
}
public class Datum
{
public string name { get; set; }
public List<FqlResultSet> fql_result_set { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
}

Categories