I have a JSON file like below, the first field has more than 500 values, how can I deserialize to C# class at bottom?
[
{
"E1001": { "MESSAGE": "", "CODE": 1001 }
},
{
"E1002": { "MESSAGE": "", "CODE": 1002 }
}
]
public class RootModel
{
public string ErrorCode { get; set; }
public ErrorDetail Details { get; set; }
}
public class ErrorDetailModel
{
public string Message { get; set; }
public string Code { get; set; }
}
I end up using AdditionalProperties, it will map all "un-mapped" values to JsonSchema object, JsonScheme give me List<key,value>, key is the error code, and value is { "MESSAGE": "", "CODE": 1001 }.
https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Schema_JsonSchema_AdditionalProperties.htm
you can use something like this
List<RootModel> rootModels = JArray.Parse(json).Select(jo =>((JObject)jo).Properties().First())
.Select(prop => new RootModel {
ErrorCode = prop .Name,
Details=prop.Value.ToObject<ErrorDetail>()
}).ToList();
Environment : -angular for the web app -c# for my api -sql server for the data base
I have this informations from my data base :
public class Traductions
{
public int Id { get; set; }
public int Lot { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public string IdLangage { get; set; }
public string LibelleLangage { get; set; }
public string Traduction { get; set; }
}
If i make a get with the api that return me that format Json informations :
[
{
"Id": 1,
"Lot" : 3,
"Code" : "ABANDONDUTRAITEMENT",
"Description" : "",
"IdLangage": "FR",
"LibelleLangage": "Francais",
"Traduction": "Abandon du traitement"
},
{
"Id": 2,
"Lot" : 3,
"Code" : "ABANDONDUTRAITEMENT",
"Description" : "",
"IdLangage": "EN",
"LibelleLangage": "English",
"Traduction": "Abandonment of processing"
}
]
But i want this type of Json format :
[
{
"Code": "ABANDONDUTRAITEMENT",
"FR": "Abandon du traitement",
"EN": "Abandonment of processing"
},
]
I want to group the informations by Code to return all the Translations (traduction) by Code.
I think i have to do it in my api and not in my angular application
How can i do it ? With linq group by?
somthing like this?
traductions.GroupBy(p => p.Code,
(k, c) => new
{
Code = k,
Data = c
}
).ToList();
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.groupby?view=net-6.0
you can change the select to be how you want to represent the data in your angular application.
My JSON Input is below. Sry it is too long
{
"status":{
"success":[
{
"User":{
"id":"1377",
"username":"Dr.Hema Sathish",
"username_url":"dr-hema-sathish",
"firstname":null,
"lastname":null,
"email":"madurai#sancheclinic.com",
"password":"6c7ab07e828828206e3d7c56c3c35cfd383960cd",
"user_level":"doctor"
},
"Speciality":{
"id":"2",
"name":"Dermatology(Skin Specialist)",
"slug":"dermatology-skin-specialist",
"image":"1438693213.png",
"status":"1",
"created":"2015-07-08 03:35:57",
"modified":"2016-09-13 13:58:36"
}
}
]
}
}
I have downloaded JSON String from URL Successfully.
static void main
{
using (var webClient = new System.Net.WebClient())
{
string json = webClient.DownloadString("http://myURL/");
Console.WriteLine(json.ToString());
}
}
Now I have to get User and Speciality objects. Its confusing to parse Array of Objects Json. How to parse it?
I have tried Deserialization. But it does not work.
How to parse it?
Your json is invalid...here is correct json
{
"status": {
"success": [{
"User": {
"id": "1377",
"username": "Dr.Hema Sathish"
},
"Speciality": {
"id": "2",
"name": "Dermatology(Skin Specialist)"
}
},
{
"User": {
"id": "1390",
"username": "Dr.Nichita Balaji"
},
"Speciality": {
"id": "2",
"name": "Dermatology(Skin Specialist)"
}
}
]
}
}
You can create below classes to deserialize it using Newtonsoft
public class User
{
public string id { get; set; }
public string username { get; set; }
}
public class Speciality
{
public string id { get; set; }
public string name { get; set; }
}
public class Success
{
public User User { get; set; }
public Speciality Speciality { get; set; }
}
public class Status
{
public List<Success> success { get; set; }
}
public class RootObject
{
public Status status { get; set; }
}
Here is the code to deserialize it
string json =
" {\r\n \t\"status\": {\r\n \t\t\"success\": [{\r\n \t\t\t\t\"User\": {\r\n \t\t\t\t\t\"id\": \"1377\",\r\n \t\t\t\t\t\"username\": \"Dr.Hema Sathish\"\r\n \t\t\t\t},\r\n \t\t\t\t\"Speciality\": {\r\n \t\t\t\t\t\"id\": \"2\",\r\n \t\t\t\t\t\"name\": \"Dermatology(Skin Specialist)\"\r\n \t\t\t\t}\r\n \t\t\t},\r\n \t\t\t{\r\n \t\t\t\t\"User\": {\r\n \t\t\t\t\t\"id\": \"1390\",\r\n \t\t\t\t\t\"username\": \"Dr.Nichita Balaji\"\r\n \t\t\t\t},\r\n \t\t\t\t\"Speciality\": {\r\n \t\t\t\t\t\"id\": \"2\",\r\n \t\t\t\t\t\"name\": \"Dermatology(Skin Specialist)\"\r\n \t\t\t\t}\r\n\r\n \t\t\t}\r\n \t\t]\r\n \t}\r\n }";
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json);
var successes = rootObject.status.success;
var specialityObjects = successes.Select(success => success.Speciality).ToList();
var users = successes.Select(success => success.User).ToList();
Console.WriteLine(users[0].id + " " + users[0].username);
Console.WriteLine(users[1].id + " " + users[1].username);
Console.WriteLine(specialityObjects[0].id + " " + specialityObjects[0].name);
Console.WriteLine(specialityObjects[1].id + " " + specialityObjects[1].name);
Console.ReadLine();
//OUTPUT
1377 Dr.Hema Sathish
1390 Dr.Nichita Balaji
2 Dermatology(Skin Specialist)
2 Dermatology(Skin Specialist)
You have to create classes according to JSON data set :
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
public class Speciality
{
public int Id { get; set; }
public string Name { get; set; }
}
Then, you should be able to Deserialize using JSON .NET library
string json = webClient.DownloadString("http://myURL/");
User u = JsonConvert.DeserializeObject<User>(json);
There may be other library available, nonetheless this one is working fine (and is available as NuGET package).
Please note this is only a sample, your code will miss several classes to properly parse your JSON (Status class, etc.).
I'm trying to process a JSON structure with Json.NET and encountered some issues:
My classes don't work when a JSON contains an unnamed array.
Json Example:
{
"graph_property" : [{
"name" : "calculation_method",
"value" : "Arithmetic"
}, {
"name" : "graph_type",
"value" : "TIME"
}
],
"measurement" : [{
"id" : "9997666",
"alias" : "Measurement (TxP)[IE]-Home Page - Total Time (seconds)",
"bucket_data" : [{
"name" : "2013-MAR-18 12:00 AM",
"id" : 1,
"perf_data" : {
"value" : "2.244",
"unit" : "seconds"
},
"avail_data" : {
"value" : "99.67",
"unit" : "percent"
},
"data_count" : {
"value" : "299",
"unit" : "#"
}
}
],
"graph_option" : [{
"name" : "perfwarning",
"value" : "-",
"unit" : "seconds"
}, {
"name" : "perfcritical",
"value" : "-",
"unit" : "seconds"
}, {
"name" : "availwarning",
"value" : "-",
"unit" : "percent"
}, {
"name" : "availcritical",
"value" : "-",
"unit" : "percent"
}, {
"name" : "bucketsize",
"value" : "86400",
"unit" : "seconds"
}, {
"name" : "rows",
"value" : "1",
"unit" : "#"
}, {
"name" : "pagecomponent",
"value" : "Total Time",
"unit" : "seconds"
}, {
"name" : "avg_perf",
"value" : "2.244",
"unit" : "seconds"
}, {
"name" : "avg_avail",
"value" : "99.67",
"unit" : "percent"
}, {
"name" : "total_datapoint_count",
"value" : "300",
"unit" : "#"
}, {}
]
}, {
"id" : "9997666",
"alias" : "Measurement (TxP)[IE]-Women - Total Time (seconds)",
"bucket_data" : [{
"name" : "2013-MAR-18 12:00 AM",
"id" : 1,
"perf_data" : {
"value" : "0.979",
"unit" : "seconds"
},
"avail_data" : {
"value" : "100.00",
"unit" : "percent"
},
"data_count" : {
"value" : "299",
"unit" : "#"
}
}
],
"graph_option" : [{
"name" : "perfwarning",
"value" : "-",
"unit" : "seconds"
}, {
"name" : "perfcritical",
"value" : "-",
"unit" : "seconds"
}, {
"name" : "availwarning",
"value" : "-",
"unit" : "percent"
}, {
"name" : "availcritical",
"value" : "-",
"unit" : "percent"
}, {
"name" : "bucketsize",
"value" : "86400",
"unit" : "seconds"
}, {
"name" : "rows",
"value" : "1",
"unit" : "#"
}, {
"name" : "pagecomponent",
"value" : "Total Time",
"unit" : "seconds"
}, {
"name" : "avg_perf",
"value" : "0.979",
"unit" : "seconds"
}, {
"name" : "avg_avail",
"value" : "100.00",
"unit" : "percent"
}, {
"name" : "total_datapoint_count",
"value" : "299",
"unit" : "#"
}, {}
]
}
],
"link" : {
"type" : "application/json",
"href" : "http://api.website.tld?format=json",
"rel" : "slotmetadata"
}
}
Class for Json.NET:
using System;
using System.Collections.Generic;
namespace CAKR.Graph
{
/// <summary>
/// Description of KN_Graph.
/// </summary>
public class GraphProperty
{
public string name { get; set; }
public string value { get; set; }
}
public class PerfData
{
public string value { get; set; }
public string unit { get; set; }
}
public class AvailData
{
public string value { get; set; }
public string unit { get; set; }
}
public class DataCount
{
public string value { get; set; }
public string unit { get; set; }
}
public class BucketData
{
public string name { get; set; }
public int id { get; set; }
public PerfData perf_data { get; set; }
public AvailData avail_data { get; set; }
public DataCount data_count { get; set; }
}
public class GraphOption
{
public string name { get; set; }
public string value { get; set; }
public string unit { get; set; }
}
public class Measurement
{
public string id { get; set; }
public string alias { get; set; }
public List<BucketData> bucket_data { get; set; }
public List<GraphOption> graph_option { get; set; }
}
public class Link
{
public string type { get; set; }
public string href { get; set; }
public string rel { get; set; }
}
public class RootObject
{
public List<GraphProperty> graph_property { get; set; }
public List<Measurement> measurement { get; set; }
public Link link { get; set; }
}
}
My code:
var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString);
I'm not sure why I don't get an object containing the data of the "Measurment" child-array.
If I insert named values, it works...
So I was struggling for quite some time to get this working. However in the end the solution is not so difficult. Hopefully with my response I will help some people.
The solution in my case was
Install JSON.net into your project by using nu.get
Make your JSON object including array's in array's, etc. Be sure that the format of the object is correct! Example...
{"ProductDetail":[
{
"ProjectImg" : "http://placehold.it/400x300",
"Category" : "Cars",
"ProjectTitle" : "Cars of the future",
"ProjectDesc" : "Test project",
"GenSpecList" : ["Specs1", "Specs2", "Specs3", "Specs4"],
"OptionList" : [{ "OptionNr" : "1",
"Options" : ["Opt1", "Opt2", "Opt3"]
},
{ "OptionNr" : "2",
"Options" : ["Opt1", "Opt2", "Opt3"]
},
{ "OptionNr" : "3",
"Options" : ["Opt1", "Opt2", "Opt3"]
},
{ "OptionNr" : "4",
"Options" : ["Opt1", "Opt2", "Opt3"]
},
{ "OptionNr" : "5",
"Options" : ["Opt1", "Opt2", "Opt3"]
},
{ "OptionNr" : "6",
"Options" : ["Opt1", "Opt2", "Opt3"]
}
],
"Articles" : [{ "tileImg" : "'Images/Project/1.jpg'",
"tileTit" : "Title1",
"tileArt" : "Article text here..."
},
{
"tileImg" : "'Images/Project/2.jpg'",
"tileTit" : "Title2",
"tileArt" : "Article text here..."
},
{
"tileImg" : "'Images/Project/3.jpg'",
"tileTit" : "Title3",
"tileArt" : "Article text here..."
},
{
"tileImg" : "'Images/Project/4.jpg'",
"tileTit" : "Title4",
"tileArt" : "Article text here..."
}
]
}
]
}
Go to json2csharp.com and copy your JSON object into the input box and click on the generate button. Copy the csharp model (this was actually the key to solve my struggle!) generated into your ViewModel.
In my case the primary class of all generated classes by json2csharp.com was the RootObject and looked like below
public class Article
{
public string tileImg { get; set; }
public string tileTit { get; set; }
public string tileArt { get; set; }
}
public class OptionList
{
public string OptionNr { get; set; }
public List<string> Options { get; set; }
}
public class ProductDetail
{
public string ProjectImg { get; set; }
public string Category { get; set; }
public string ProjectTitle { get; set; }
public string ProjectDesc { get; set; }
public List<string> GenSpecList { get; set; }
public List<OptionList> OptionList { get; set; }
public List<Article> Articles { get; set; }
}
public class RootObject
{
public List<ProductDetail> ProductDetail { get; set; }
}
Then use the following code in the controller (just copied the complete file here)
using Project.Details; //<-- this is my ViewModel namespace name
using Newtonsoft.Json;
using System.IO;
using System.Threading.Tasks;
namespace WebApplication.Controllers
{
public class JSONController : Controller
{
//
// GET: /JSON/
public async Task<ActionResult> Index()
{
StreamReader file = new StreamReader("C:\\Users\\YourName\\etc\\File.json");
String json = await file.ReadToEndAsync();
var Project = JsonConvert.DeserializeObject<RootObject>(json);
return View();
}
}
}
Now everything should work fine, array's in array's etc.
Hope that you found my solution helpful, note I'm not a die hard programmer so if I miss things on efficency I hope to recieve some tips from you to improve this code...
Best regards,
Raymond
You are almost there. Just use
var myObject = JsonConvert.DeserializeObject<CAKR.Graph.RootObject>(MyJsonString);
instead of
var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString);
First of all, you do not really need to name all the properties of your Measurement class exactly as they are presented in MyJsonString. You can use JsonProperty attribute and decorate your class properties.
Another thing is if you want to deserialize part of your MyJsonString and extract only array of Measurement, you should provide correct T type for Deserialize method (in your case it's IEnumerable<Measurement>.
The following code should help:
dynamic context = JObject.Parse(MyJsonString);
var myObject = JsonConvert.DeserializeObject<IEnumerable<Measurement>>(context.measurement.ToString());
I use a very simple method to Deserialize Json Arrays. Instead of using a ton of public classes with numerous public variables. I just use a Dynamic object and pass json as an object to JSONConvert.DeserializeObject.
This is how it would work. Say I have the following JSON:
string json = { 'Name': 'John Doe',
'Address': { 'City': 'Atlanta', 'State': 'GA' },
'Age': 30}
I can pass string json to the JSONConvert.DeserializeObject.
dynamic outputArray = JsonConvert.DeserializeObject(json);
Then using the dynamic item that was just created I can collect Json data like so.
string getName = outputArray.Name //This will return "John Doe"
If you have an array inside your Json you can use
string getCity = outputArray.Address.City; //This will return "Atlanta".
It's very easy to change where you pull data from without having a cluster of public variables... You can still save the values to public variables if you want.
The following is how I use the complete method:
using (var client = new WebClient())
{
string json = client.DownloadString(url);
string output = json.ToString();
dynamic outputArray = JsonConvert.DeserializeObject(output);
string _age = outputArray.age;
string appID = outputArray.data.app_id;
Debug.Write(outputArray.Something); //Just match value of json
}
I've below function which fetches facebook data and return it as string.
public static string GetUserNewsFeed(string strAccessToken)
{
Dictionary<string, object> PostDetail = new Dictionary<string, object>();
DateTime CreatedDateTime = DateTime.Today.AddDays(-90);
var epoch = (CreatedDateTime.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
PostDetail.Add("Posts", "SELECT post_id,source_id FROM stream WHERE filter_key in (SELECT filter_key FROM stream_filter WHERE uid=me() AND type='newsfeed') and (likes.count > 0 or comments.count > 0) and created_time > " + epoch);
PostDetail.Add("PostComments", "select post_id,fromid from comment where post_id in (select post_id from #Posts)");
PostDetail.Add("PostLikes", "SELECT object_id,post_id,user_id FROM like WHERE post_id in (select post_id from #Posts)");
string Json = HttpUtility.UrlEncode(Newtonsoft.Json.JsonConvert.SerializeObject(PostDetail));
return RunFQLQuery(Json, strAccessToken);
}
Here's the code that calls this function and convert it to Jobject using Json.NET :
strFeed = FacebookAPI.GetUserNewsFeed(Convert.ToString(Session["access_token"]));
JObject objStreamData = JObject.Parse(strFeed);
var PostResponse = objStreamData.SelectToken("data[0]");
Below line deserialize it to NewsFeedPost Class :
var Posts = JsonConvert.DeserializeObject<NewsFeedPost>(PostResponse.ToString());
And below is the class :
public class NewsFeedPost
{
public string name { get; set; }
public List<Post> fql_result_set { get; set; }
}
public class Post
{
public string post_id { get; set; }
public string source_id { get; set; }
}
Now problem is when I change my NewsFeedPost class to below it throws error "Cannot deserialize JSON object into type 'BAL.NewsFeedPost'" :
public class NewsFeedPost : IEnumerable<Post>
{
public string name { get; set; }
public List<Post> fql_result_set { get; set; }
public IEnumerator<Post> GetEnumerator()
{
foreach (Post item in fql_result_set)
{
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Below is the sample of Json Response :
{
"data": [
{
"name": "Posts",
"fql_result_set": [
{
"post_id": "1"
},
{
"post_id": "2"
}
]
},
{
"name": "PostComments",
"fql_result_set": [
{
"post_id": "3",
"fromid": 4
},
{
"post_id": "5",
"fromid": 6
}
]
},
{
"name": "PostLikes",
"fql_result_set": [
{
"object_id": 7,
"post_id": "8",
"user_id": 9
},
{
"object_id": 10,
"post_id": "11",
"user_id": 12
}
]
}
]
}
I just want to enumerate through list and create comma delimited list and save it to db. Can anybody throw some light what needs to be done? How can I get the Count and Length Property for List?
Two things:
1) Add JsonObjectAttribute to NewsFeedPost:
[JsonObject]
public class NewsFeedPost : IEnumerable<Post>
2) To deserialize that JSON which you show, you need another class:
public class NewsFeedPosts
{
public List<NewsFeedPost> Data { get; set; }
}
and then you'd call your deseralize with that class as what you want deserialized:
var Posts = JsonConvert.DeserializeObject<NewsFeedPosts>(PostResponse.ToString());
You may want to try a cast on the DeserializeObject
var Posts = JsonConvert.DeserializeObject<NewsFeedPost>((NewsFeedPost)PostResponse.ToString());