JSON Serializing confusion - c#

I'm simply building a test Web API that takes a JSON payload and will simply send back the data in the array portion from my MVC Controller.
This is my current JSON string when serialized by my populated classes:
{"JobList":[{"ID":1,"Name":"Dave","Age":23,"StartDate":"10/23/2013 6:22:50 AM","JobTitle":"Developer"},{"ID":2,"Name":"John","Age":44,"StartDate":"10/23/2013 6:22:50 AM","JobTitle":"QA"},{"ID":3,"Name":"Dave","Age":23,"StartDate":"10/23/2013 6:22:50 AM","JobTitle":"Senior Developer"}]}
This is the object used to create this JSON:
var jobList = new JobsList()
{
JobList = new List<Jobs>()
{
new Jobs()
{
Age = 23,
ID = 1,
Name = "Dave",
StartDate = DateTime.Now.ToString(),
JobTitle = "Developer"
},
new Jobs()
{
Age = 44,
ID = 2,
Name = "John",
StartDate = DateTime.Now.ToString(),
JobTitle = "QA"
},
new Jobs()
{
Age = 23,
ID = 3,
Name = "Dave",
StartDate = DateTime.Now.ToString(),
JobTitle = "Senior Developer"
}
}
};
Here are my individual classes:
JobsList Class:
public class JobsList:IJobList
{
#region IJobList Members
public List<Jobs> JobList
{
get;
set;
}
#endregion
}
Jobs Class:
public class Jobs:Interfaces.IJobs
{
#region IJobs Members
public int ID
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public string StartDate
{
get;
set;
}
public string JobTitle
{
get;
set;
}
#endregion
}
When I convert my JSON to produce classes through the use of JSON2Csharp the classes are produced as shown:
public class JobList
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string StartDate { get; set; }
public string JobTitle { get; set; }
}
public class RootObject
{
public List<JobList> JobList { get; set; }
}
This to me seems incorrect. Can anyone explain why I am not getting a 'Jobs' node in my JSON set to the JobsList array? And why do the generated JSON2CSharp classes map my 'Jobs' class as a JobList class?

Basically, it's because deserializer (in this case, JSON2CSharp) doesn't know what you named your original classes. Or how you structured them, for that matter. It doesn't know about any of that stuff you posted below "my current JSON string."
When you hand it that JSON object, that's all the information it is working with. So, it can tell that there's some sort of object (which it calls "RootObject"), which has an array of objects called "JobList". So it called the class "JobList". It had a choice there -- it could have simply called the list "JobList" and named the object something else... but it has no way of knowing that it was originally from an object named "Jobs", because that's not in the JSON. A different deserializer may have done it differently.
I am not familiar with JSON2CSharp specifically, so I don't know if it can do this, but there are frameworks that, given the object definition, can parse a JSON string with consistently named fields and load it into that object. For example, with Json.NET, you can do something like this:
JobsList jobList = JsonConvert.DeserializeObject<JobsList>(JsonString);

Related

How to Convert JSON object to Array

I am new to C# need help to convert json Object to Array
convert this json
[
{
"Id": 1000,
"Name": "May",
"Address": "odyssey",
"Country": "USA",
"Phone": "12345"
}
]
To
var details = {1000,May,odyssey,USA,12345};
Use Newtonsoft.Json to deserialize JSON to a specified .net type. You can deserialize to a class too, see below:
public class Person
{
public int Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public string Phone {get;set;}
}
var details = JsonConvert.DeserializeObject<Person>(json);
You are going to have to deserialize the Json String. Deserialize into array of objects.
JavaScriptSerializer js = new JavaScriptSerializer();
yourClass[] items = js.Deserialize<Yourclass[]>(yourJSONcontent);
Steps:
1. Create Model.
2. Get Data in string
3.Deserialize Object
And if you are confused How to create C# model from the json then use this link.
https://app.quicktype.io
Use This Model.
public class Test
{
[JsonProperty("Id")]
public long Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Address")]
public string Address { get; set; }
[JsonProperty("Country")]
public string Country { get; set; }
[JsonProperty("Phone")]
[JsonConverter(typeof(ParseStringConverter))]
public long Phone { get; set; }
}
string data="Your Json String"
var details = JsonConvert.DeserializeObject<Test>(data);
To make a list from your json values you can use a JObject, you don't have to know the objects stored in your Json in contrary to the others question.
JObject myObject = JsonConvert.DeserializeObject<JObject>(myJson);
List<object> myList = new List<object>();
foreach (var element in myObject)
{
myList.Add(element.Value);
}
If you already know what your json is made of, you can create a class that represent your object and implement the interface IEnumerable.
var myObject = JsonConvert.DeserializeObject<MyClass>(myJson);
var myArray = myObject2.ToArray():
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Country { get; set; }
public int Phone { get; set; }
public object[] ToArray()
{
return new object[]
{
Id,
Name,
Address,
Country,
Phone
};
}
}
NB : the variable myJson in the previous codes is a string that represent your json as var myJson = "{\"Id\": 1000,\"Name\": \"May\",\"Address\": \"odyssey\",\"Country\": \"USA\",\"Phone\": \"12345\"}";

How to set list A equal to list B, where on B a property does not exist which does exist on A

I have a C# list which is of type Person. This list needs to be converted into JSON data format. The Person C# class look like this:
public class Person
{
public int ID { get; set; }
public static int PSID = 1;
public string name { get; set; }
public string nameToken { get; set; }
public double DOB { get; set; }
public List<Award> awards { get; set; }
public List<Link> links { get; set; }
public Person()
{
awards = new List<Award>();
links = new List<Link>();
ID = PSID;
PSID++;
}
}
As I am required to convert a C# list of type Person into JSON. I made another Class in C# called PersonJS. It is exactly like the Person C# class the only difference is that I have removed some of the properties that are not required in the JSON front-end. Namely: nameToken, PSID.
public class PersonJS
{
public int ID { get; set; }
public string name { get; set; }
public double DOB { get; set; }
public List<AwardJS> awards { get; set; }
public List<Link> links { get; set; }
}
One of the properties of PersonJS is a List called awards which is of Type AwardJS. A problem occurs below because I try and equal Person.awards List equal to PersonJS.awards List. However, they are of difference types so it is not possible to equal both lists. The reason why I have put them equal to different types is because the JSON data does not need all of the properties that I have used in C#. So I made two classes Award and AwardJS. The only difference is that Award contains a property called filmWebToken whereas AwardJS does not.
public class Award
{
public int filmID { get; set; }
public int categoryID { get; set; }
public string filmWebToken { get; set; }
}
public class AwardJS
{
public int filmID { get; set; }
public int categoryID { get; set; }
}
In my code I iterate over all of the properties in C# list of type Person and I attempt to create a personjs object and add it to a PersonJS C# list. The PersonJS list will go back to the front-end as JSON. However, because the award property in the class PersonJS is different to the award property in Person I get the error "Cannot implicitly convert type AwardJS to Award". The reason I get this error is because PersonJS does not contain filmWebToken which exists in the Person class. I don't want the filmWebToken to be in the PersonJS list as it is not meant to be a property in my JSON data. However, as there are property fields in Person.Award I still want access to: filmID and CategoryID how can I ignore/by-pass the filmWebToken field. This is what I have tried:
List<Person> allPersons = DataRepository.GetAllPersons(); // contains the C# data
List<PersonJS> personjs = new List<PersonJS>(); // empty to start with
foreach (var person in allPersons)
{
foreach (var award in person.awards)
{
personjs.Add(
new PersonJS
{
ID = person.ID,
links = person.links,
name = person.name,
DOB = person.DOB,
awards = person.awards // The types are not equal: Person contains filmWebToken whereas PersonJS does not
});
}
}
Add a method called ToAwardJS in Award:
public AwardJS ToAwardJS() {
return new AwardJS { filmID = this.filmID, categoryID = this.categoryID };
}
Then when you create the PersonJS object, do:
new PersonJS
{
ID = person.ID,
links = person.links,
name = person.name,
DOB = person.DOB,
awards = person.awards.Select(x => x.ToAwardJS()).ToList(),
});
What serializer are you using? Most provide attributes to specify which members to include in the serialization. For example, the DataContractJsonSerializer uses [DataContract] and [DataMember]. I think Json.net uses [JsonIgnore]. There's no need for multiple classes.
void Main()
{
var jsSer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(Person));
var p = new Person {
ID = 1,
name = "John",
DOB = 1234.5,
nameToken = "token"
};
string result = null;
using (var ms = new MemoryStream())
{
jsSer.WriteObject(ms, p);
byte[] json = ms.ToArray();
ms.Close();
result = Encoding.UTF8.GetString(json, 0, json.Length);
}
Console.WriteLine(result);
}
[DataContract]
public class Person
{
//included
[DataMember]
public int ID { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string nameToken { get; set; }
[DataMember]
public double DOB { get; set; }
//ignored
public static int PSID = 1;
public List<string> awards { get; set; }
public List<string> links { get; set; }
public Person()
{
awards = new List<Award>();
links = new List<Link>();
ID = PSID;
PSID++;
}
}
Result:
{"DOB":1234.5,"ID":1,"name":"John","nameToken":"token"}

C# DataContract custom deserialisation

I need help with a DataContract problem. I have a web service that outputs JSON that needs to map to a C# object.
The important data returned from the API is wrapped in a "data" key of the JSON object but this is not important to me and I would like to discard it and have the JSON deserialised into the Item class. The Item class is used elsewhere and I would really like to leave it unchanged if possible.
Is there a way to change how data from the JSON is deserialised into the Item object but leave the Item object serialisation as default?
Currently the code is doing var item = await response.Content.ReadAsAsync<Item>(); to build the object from the API response.
If its not possible to leave the Item class unchanged then can you suggest the easiest modification to achieve the goal.
JSON:
{
"data": {
"id": "13c38fe9-6d9f-4a11-8eda-d071f2a99698",
"item_type": 100,
"item_name": "My Item Name"
}
}
C# Object:
[DataContract]
public class Item
{
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "item_type")]
public int? ItemType { get; set; }
[DataMember(Name = "item_name")]
public string ItemName { get; set; }
}
Any help would be greatly appreciated as C# is not normally a language I work with.
Based on your json, your data is coming in a format of a class like this
[DataContract]
public class Wrapper
{
[DataMember(Name = "data")]
public Item item { get; set; }
}
[DataContract]
public class Item
{
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "item_type")]
public int? ItemType { get; set; }
[DataMember(Name = "item_name")]
public string ItemName { get; set; }
}
Your response is in the format of a wrapper where data is an property of type Item. Add a wrapper to your contracts, it should work fine.
You could run it like this, to check if your serialized string is in the same format.
Wrapper tempData = new Wrapper() { item = new Item() {
Id = new Guid("13c38fe9-6d9f-4a11-8eda-d071f2a99698"),
ItemName = "My Item Name",
ItemType = 100 } };
var serializedDta = JsonConvert.SerializeObject(tempData);

How to Convert Json Object to Array in C#

I am trying to convert a JSON object in to C# array.
this is the JSon I Getfrom the Server webrequest response:
string result = sr.ReadToEnd(); // this line get me response
result = {
"subjects": [{
"subject_id": 1,
"subject_name": "test 1",
"subject_class": 4,
"subject_year": "2015",
"subject_code": "t-1"
},{
"subject_id": 2,
"subject_name": "test 2",
"subject_class": 5,
"subject_year": "",
"subject_code": "t-2"
}]
};
dynamic item = JsonConvert.DeserializeObject<object>(result);
string iii = Convert.ToString(item["subjects"]);
I want to Get the Subjects and Save them in Array so i can use them for other purpose.
I use these to Method but always got the empty values.
List<subjects> subject1 = (List<subjects>)JsonConvert.DeserializeObject(iii, typeof(List<subjects>));
and
subjects[] subject2 = JsonConvert.DeserializeObject<subjects[]>(iii);
Please Help Me to Solve this.
And my Subject Class is..
class subjects
{
public int id { get; set; }
public string name { get; set; }
public int class_name { get; set; }
public string year { get; set; }
public string code { get; set; }
}
The property names won't match as is, because you subjects class don't have the 'subject_' prefix the JSON object has. Easiest fix is to change your property names as shown in Ali's answer. Just in case you need to keep your property names as is, you can also use a JsonProperty attribute to alter the serialization names (perhaps there's a more generic way using some sort of converter, but didn't think the amount of properties needed it)
class subjects
{
[JsonProperty("subject_id")]
public int id { get; set; }
[JsonProperty("subject_name")]
public string name { get; set; }
[JsonProperty("subject_class")]
public int class_name { get; set; }
[JsonProperty("subject_year")]
public string year { get; set; }
[JsonProperty("subject_code")]
public string code { get; set; }
}
If you never need the root subjects you can also skip it without dynamic or an extra class with something like:
subjects[] arr = JObject.Parse(result)["subjects"].ToObject<subjects[]>();
(JObject is part of the namespace Newtonsoft.Json.Linq )
You need to create a structure like this:
public class Subjects
{
public List<Subject> subjects {get;set;}
}
public class Subject
{
public string subject_id {get;set;}
public string subject_name {get;set;}
}
Then you should be able to do:
Subjects subjects = JsonConvert.DeserializeObject<Subject>(result);

Iterate through complex object to set view model values

Let's say the following complex Json response was sent by back by a remote service
{
"query": "search",
"skills": {
"skill": [
"php",
"java",
"C#"
]
},
"results": [
{
"name": "jim",
"dept": "technology"
},
{
"name": "peter",
"dept": "technology"
}
]
}
Its format is fixed and I've stored it as a String
string jsonString = JsonConvert.SerializeObject(Res);
and I have a Response Model
public class Response
{
public string query { get; set; }
public Skill skills { get; set; }
public List<Employees> results { get; set; }
}
public class Skill
{
public List<string> skill { get; set; }
}
public class Employees
{
public string name { get; set; }
public string dept { get; set; }
}
and I have a View Model
public class EmployeeExperts {
public List<EmployeeInfo> employee { get; set; }
}
public class EmployeeInfo {
public string name { get; set; }
public string dept { get; set; }
}
and I have deserialized the response to the class
var Obj = JsonConvert.DeserializeObject<Response>(jsonString);
How then would I iterate through Obj and hook it up, from the controller to my EmployeeExperts View Model?
e.g. EmployeeExperts.EmployeeInfo[0] = Response.results[0].name
I'm just trying to properly parse a response and show it on the view. Additionally, I've got another question - Is this the right way of doing all of this?
First I noticed your Employees and EmployeeInfo is same, it does not need to.
You can change EmployeeExperts class as follows:
public class EmployeeExperts {
public List<Employee> Employees { get; set; }
}
And now you can write:
var Obj = JsonConvert.DeserializeObject<Response>(jsonString);
var experts = new EmployeeExperts();
// You can directly assign list like this and iterate through `experts.Employees` list
experts.Employees = obj.results;
Note: I have not tested above code, you may need to cast results into List<Employee>.
Additionally, I've got another question - Is this the right way of doing all of this?
I have used AutoMapper for such object to object conversion. It is flexible and does handle 95% cases. In those 95% cases it saves a lot of your time that you otherwise spend in conversion.
Give it a try and see if serves your purpose.

Categories