Nested JSON-object in c# - c#

I want to create a multidimensional json object based on a c# class. I normally do it like this:
public class foo
{
public string name { get; set; }
public int age { get; set; }
}
And serialize a new instance of the class with a JavaScriptSerializer. But lets say that i want to add another json array containing the persons friends inside the main json array. Example array: Accessing data in a multidimensional JSON array with jQuery
Hope you get the idea. Thanks

If I get your question corect, something like this should work...
public class Person
{
public string name { get; set; }
public int age { get; set; }
public List<Person> Friends { get; set; }
}

How are you creating the JSON version of your class, foo?
JavaScriptSerializer and Controller.JSON (in MVC) support serializing IEnumerable derived types, so you could have the class:
public class foo
{
public string name { get; set; }
public int age { get; set; }
public List<Bar> friends {get; set;}
}
and your JSON serialized class would include the list of Bar objects.

Related

Dynamic/Expando and JSON

There's a lot of Qs on this, but I need a solution without JSON.Net, etc. - I must use the canned stuff in Asp.Net MVC.
How can I serialize a POCO with a dynamic property - and get all the static properties, too? What I found was the dynamic only, or the static type which is easy.
e.g.
public class ReturnThisClassAsJSON {
public int Id {get; set; }
public string Name { get; set; }
public ContainedClass ContainedContents { get; set; }
}
public class ContainedClass {
public int Order { get; set; }
public string Label { get; set; }
public dynamic DynamicInfo { get; set; }
public List<dynamic> DynamicList { get; set }
}
My own answer:
I replaced the dynamic from the DynamicInfo and DynamicList from the ContainedClass with static types.
With the dynamic, I had 1 of 2 choices. Either serialize the dynamic to a string in its own serialization call using above SO question 5156664. (Which left me with the rest of the class I also wanted serialized and merged with it, thus this question). Or, incur this error:
"A circular reference was detected while serializing an object of type 'System.Reflection .RuntimeModule' ".
when attempting a single serialization call on the ContainedClass.
So, I transferred the dynamics into static-typed classes:
public class ColumnValue
{
public string Name { get; set; }
public string Value { get; set; }
}
public class DynamicRow
{
public List<ColumnValue> ColumnValue { get; set; }
}
and, change ContainedClass to this:
public class ContainedClass
{
public List<ColumnValue> DynamicInfo { get; set; }
public List<DynamicRow> Data { get; set; }
}
And, it serializes using out-of-the-box Asp.Net MVC:
return Json(ReturnThisClassAsJSON, JsonRequestBehaviour.AllowGet);

deserialize json object does not work

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);

JSON.Net Deserialization of non-generic Root Objects

I'm currently working on a project where I make a request to the Riot Games API, parse the JSON, and do some stuff with it. I have the request working, and I know I'm getting valid JSON. My issue is using JSON.Net to deserialize the JSON.
The JSON is of the following structure:
{
"xarcies": {
"id": 31933985,
"name": "Farces",
"profileIconId": 588,
"revisionDate": 1450249383000,
"summonerLevel": 30
}
}
I want to load this data into the following class
[JsonObject(MemberSerialization.OptIn)]
class Summoner
{
[JsonProperty("id")]
public long id {get;set;}
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("profileIconId")]
public int profileIconId { get; set; }
[JsonProperty("revisionDate")]
public long revisionDate { get; set; }
[JsonProperty("summonerLevel")]
public long summonerLevel { get; set; }
}
The issue I'm having is that because I'm given a "xarcies" object that contains the information I need, I'm not sure how to go about designing a class that can accept the JSON data. I've seen some examples that use a RootObject class to take the object and that class has a subclass that all the pairs are put into, but I can't seem to get it to work. Every time I run it the attributes for the object end up being NULL.
You can deserialize your JSON as a Dictionary<string, Summoner>:
var root = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(jsonString);
The dictionary will be keyed by the user name, in this case "xarcies". See Deserialize a Dictionary.
I just used json2csharp to create the following class (its types look a bit different then yours):
public class UserData
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public long revisionDate { get; set; }
public int summonerLevel { get; set; }
}
public class RootObject
{
public KeyValuePair<string, UserData> value { get; set; }
}

Map JSON object to c# class property

I'm getting a bunch of JSON data back from a 3rd party API like this:
returnValue = data["value"].ToObject<List<T>>();
All but one of the fields are just basic name:value pairs like this:
"Name":"Value"
I map the values I need to a class like this:
public sealed class Project
{
public string Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public DateTime ProjectDateLocal { get; set; }
public string ParentFolderName { get; set; }
public string ParentFolderId { get; set; }
//causing trouble
public Int32 ProjectTypeId { get; set; }
public string PlayerUrl
{
get
{
return "http://em.edu.edu/prj/Play/" + this.Id;
}
}
}
However, one name:value pair is complicated like this:
"CustomFieldValues":[
{
"FieldName":"ProjectTypeId","FieldDefinitionId":"37a2ffeb3bd441f6a60158458910a04d40","DataType":"Integer","Value":"100105"
}
]
I only need the FieldName(ProjectTypeId) and Value, is there a way to get just that have the class recognize that and set it in my ProjectTypeId property?
Thanks!
As #viggity stated, you can use Newtonsoft for your problem and the solution provided is good. The only thing you have to do is provide a good string json to the Deserializer.
If you want a simpler solution why don't you use data["value"].ToObject<List<Project>>() ?
Note: Assigning attributes like [JsonProperty("FieldNameFromJson")] is ussefull for mappings.
See this post for more info about how you can do this.
Use Json.net to deserialize JsonConvert.Deserialize<Project>(jsonStringContent)
Json.net will go multi levels, just add a new class and have your Project have that property.
public class CustomFieldValue
{
public string FieldName {get;set;}
public string Value {get; set;}
}
and add a list of them to your Project.
public sealed class Project
{
public string Id { get; set; }
...
public List<CustomFieldValue> CustomFieldValues { get; set; }
}
Json.net won't have any problem with it. If you don't add FieldDefinitionId, etc then Json.net will just ignore it.
http://www.newtonsoft.com/json

Json Deserialisation with subarrays doesn't contain values

I am trying to deserialise a json object. The Problem is that the the object also contains subarrays
http://i.imgur.com/WWwEVLR.png
Except for the subarrays everything is working.
I am using Newtonsoft.Json;
Here is my class
public string date_updated { get; set; }
public string date_expires { get; set; }
This is working fine.
For the subarray I did it that way:
public JsonArray contacts { get; set; }
This is my method to deserialise it:
var json = await webClient.GetAsync(new Uri(uri));
var result = await json.Content.ReadAsStringAsync();
Model = JsonConvert.DeserializeObject<Model>(result);
The Array is created well with all fields needed, but the values are not working.
The values are just: Windows.Json.JsonObject as on the picture below.
http://i.imgur.com/Q8bpCoD.png
Why is he not writing the values? How can I get them?
Thank you for your help.
The values are working fine. Using JsonArray tells the deserializer to convert the JSON data to something that is compatible with the type JsonArray. This type is simply a 1:1 representation of the JSON string underneath and is not deserialized into useful data automatically for you.
Also, JsonArray is not even part of the Json.Net library. As the debugger is telling you, it is part of the Windows.Data.Json namespace which is in a different library. You could still access the data directly from each JsonObjects using the various Get methods inside the class ( http://msdn.microsoft.com/en-us/library/windows.data.json.jsonobject.aspx ) but this is probably not the way you want to go.
In your case, you should create a class that represents the data you have inside each of those arrays. If not all entries in the array contains all of the properties of your class, don't worry. Json.Net will simply leave their value empty when deserializing. This will look like:
public class Contact
{
public string type { get; set; }
public string name { get; set; }
public string organization { get; set; }
public string full_address { get; set; }
etc.
}
For good measure, you should also respect the C# naming convention which states that properties should use CamelCase names. To help you with this, you can use the JsonProperty attribute like so:
public class Contact
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("organization")]
public string Organization { get; set; }
[JsonProperty("full_address")]
public string FullAddress { get; set; }
etc.
}
Then, you can replace the type of your contacts property to List<Contact> and the data will be automatically deserialized to a format that you can easily use.
Define new class
class Contact {
public string type { get; set; }
public string name { get; set; }
// etc
}
and modify your ReqInfo_WhoIs_Model class
public string date_updated { get; set; }
public string date_expires { get; set; }
public List<Contact> contacts { get; set; }

Categories