What is the best way to desirialize this string of json? - c#

I was wondering how I could at best deserialize this json string. For doing that I am using Newtonsoft.json as a plugin with Xamarin.
I only need the parts that says "transaction" and the array in it "transactions" in a list.
{
"id": 999,
"transactions": [
{
"order": 1,
"displayName": "01_lgn",
"transaction": {
"id": 7791,
"name": "01_lgn",
"description": null,
"warning": 1,
"poor": 2,
"timeOut": 45,
"tolerated": 3,
"frustrated": 7,
"state": 1,
"includeInThroughputCalculation": true
}
}
{
"order": 2,
"displayName": "02",
"transaction": {
"id": 7793,
"name": "02",
"description": null,
"warning": 1,
"poor": 2,
"timeOut": 45,
"tolerated": 3,
"frustrated": 7,
"state": 1,
"includeInThroughputCalculation": true
}
}
],
"defies": null,
"state": 1,
"reportDisplayName": "testSomething"
}
What I already have tried is to put it in a strongly typed class and then make a list of it.
public class testTransaction
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("state")]
public int State { get; set; }
[JsonProperty("reportDisplayName")]
public string ReportDisplayName { get; set; }
[JsonProperty("transactions")]
public List<testTransactions> testTransactions { get; set; }
}
public class testTransactions
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("description")]
public object Description { get; set; }
[JsonProperty("warning")]
public int Warning { get; set; }
[JsonProperty("poor")]
public int Poor { get; set; }
[JsonProperty("timeOut")]
public int TimeOut { get; set; }
[JsonProperty("tolerated")]
public int Tolerated { get; set; }
[JsonProperty("frustrated")]
public int Frustrated { get; set; }
[JsonProperty("state")]
public int State { get; set; }
[JsonProperty("includeInThroughputCalculation")]
public bool IncludeInThroughputCalculation { get; set; }
}
But when I try to deserialize it in this way the "searchResult" is empty and I see that nothing is added to the list.
var bleh = jsonstring;
JObject parsedketenObject = JObject.Parse(bleh);
IList<JToken> jTokenResults1 = parsedketenObject;
IList<JToken> jTokenResults2 = parsedketenObject ["transactions"].Children ().ToList ();
IList<JToken> jTokenResults3 = parsedketenObject["transactions"][0]["transaction"].Children().ToList();
_Transactions_list = new List<testTransaction>();
foreach (JToken result in jTokenResults2)
{
testTransaction searchResult = JsonConvert.DeserializeObject<testTransaction>(result.ToString());
_Transactions_list.Add(searchResult);
}

Firstly, the JSON seems to be malformed, you are missing comma.
{
"id": 999,
"transactions": [
{
"order": 1,
"displayName": "01_lgn",
"transaction": {
"id": 7791,
"name": "01_lgn",
"description": null,
"warning": 1,
"poor": 2,
"timeOut": 45,
"tolerated": 3,
"frustrated": 7,
"state": 1,
"includeInThroughputCalculation": true
}
}, <-------- HERE
{
"order": 2,
"displayName": "02",
"transaction": {
"id": 7793,
"name": "02",
"description": null,
"warning": 1,
"poor": 2,
"timeOut": 45,
"tolerated": 3,
"frustrated": 7,
"state": 1,
"includeInThroughputCalculation": true
}
}
],
"defies": null,
"state": 1,
"reportDisplayName": "testSomething"
}
Additionally, try these for your POCO instead:
public class TransactionDetails
{
public int id { get; set; }
public string name { get; set; }
public object description { get; set; }
public int warning { get; set; }
public int poor { get; set; }
public int timeOut { get; set; }
public int tolerated { get; set; }
public int frustrated { get; set; }
public int state { get; set; }
public bool includeInThroughputCalculation { get; set; }
}
public class Transaction
{
public int order { get; set; }
public string displayName { get; set; }
public TransactionDetails transaction { get; set; }
}
public class RootObject
{
public int id { get; set; }
public List<Transaction> transactions { get; set; }
public object defies { get; set; }
public int state { get; set; }
public string reportDisplayName { get; set; }
}
Then you can use
var x = JsonConvert.DeserializeObject<RootObject>(blah);
x will contain transactions, which is already a list.

This method is not strongly typed, but it will work:
var jsonString = GetTheJson(); // however you get your json
dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);
foreach (var txn in jsonObject.transactions)
{
Console.WriteLine("{0} {1} {2}", txn.order, txn.displayName, txn.transaction.id);
}

The best way to serialize/deserialize a json string to json object is using Google Gson library. You should create DTO files and use its type to serialize the string.
The documentation can be found here: https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/Gson.html

Related

Importing Json to objects in C#

I have been working trying to import a list of objects from Json to C#.
The Json structure is:
"meta": {
"file_version": 11,
"machine_number": 210xxxxx,
"software": {
"software_date": "",
"software_version": ""
},
"saved": {
"user": "Bxxxxxx",
"date": "20220810",
"time": "132156"
},
"application": {
"name": "Support",
"type": "xxxxx_Support"
},
"validity": {
"machine_model": "xxx",
"arm_assembly": "xxx",
"boom_pedestal": "xxx"
}
},
"data": {
"data532": {
"number": 54,
"name": "Abstützung vorne - zulässige vertikale Beinkraft (P1.Q1)",
"format": 0,
"digit": 0,
"unit": 10,
"category": 0,
"min": 0,
"max": 1000000,
"value": 225000,
"hexvalue": "0x00036EE8",
"binvalue": "0b00000000000000110110111011101000"
},
"data533": {
"number": 55,
"name": "Abstützung vorne - zulässige vertikale Beinkraft (P1.Q2)",
"format": 0,
"digit": 0,
"unit": 10,
"category": 0,
"min": 0,
"max": 1000000,
"value": 0,
"hexvalue": "0x00000000",
"binvalue": "0b00000000000000000000000000000000"
.
.
.
.
.
My problem is that I need to set up the objects DataXXX in C#.
Im trying with:
var dataconfig = JsonConvert.DeserializeObject<Data>(jsonfile);
Where class Data is
public class Data
{
public int number { get; set; }
public string name { get; set; }
public int format { get; set; }
public int digit { get; set; }
public int unit { get; set; }
public int category { get; set; }
public int min { get; set; }
public int max { get; set; }
public int value { get; set; }
public string hexvalue { get; set; }
public string binvalue { get; set; }
}
But my dataXXX is inside another object called Data so the code is not working. And it's not a list also.
In Newtonsoft.Json, there are two API's, one high-level (JsonConvert) and one low-level (Linq-to-Json). JsonConvert is great for parsing if the data matches the C# class structures you have. Linq-to-Json is great for custom processing and flexibility.
In your case, since your property names have numbers in them that you need to standardize to match C# classes, you probably need to use Linq-to-Json. This parses JSON into objects similar to a Dictionary. Here are the intro docs.
If you need only a data part, you can parse the json at first, after this you can deserialize any part
var jsonParsed = JObject.Parse(jsonFile);
Dictionary<string,Data> dataconfig = jsonParsed["data"].ToObject<Dictionary<string,Data>>();
you should use Dictionary
public class Data {
public Dictionary<string,DataModel> data {get; set;}
}
public class DataModel {
public int number { get; set; }
public string name { get; set; }
public int format { get; set; }
public int digit { get; set; }
public int unit { get; set; }
public int category { get; set; }
public int min { get; set; }
public int max { get; set; }
public int value { get; set; }
public string hexvalue { get; set; }
public string binvalue { get; set; }
}
with Newtonsoft:
JsonConvert.DeserializeObject<Data>(jsonfile); //jsonfile must be includes data.
with System.Text.Json
JsonSerializer.Deserialize<Data>(jsonfile);

How to convert JSON response object (having dynamic objects) into C# classes or usable result object

I am using an API for car HP and PCP details. When API returns the response object it has some dynamic object and objects names depending upon the parameters given during JSON call input parameters. Please tell me how can I convert / deserialize this response object into C# object. I tried JSON convert to C# classes but didn't get required results. Given below in API response object. I need to parse this result object into C# object so i can use it for displaying required values on front end.
JSON Response / Result Object
{
"success": true,
"data": {
"hp": {
"58995": {
"48": {
"40": {
"9000": [
{
"balance": 58955,
"first": 1403.62,
"regular": 1403.62,
"final": 1413.62,
"total": 67423.76,
"charges": 8428.76,
"apr": 6.92,
"apr_nofees": 6.91,
"term": 48,
"flat": 3.57,
"fee_front": "0.00",
"fee_back": "10.00",
"fee_spread": 0,
"ref": "1000.00",
"ho": 0,
"ho_a": 0,
"sb": 0,
"id": "12",
"product_name": "HP/ML No Fees",
"excess_mileage": false
}
]
}
}
}
},
"pcp": {
"58995": {
"48": {
"40": {
"9000": [
{
"balance": 58955,
"first": 1251.04,
"regular": 1251.04,
"final": 8386,
"total": 68475.92,
"charges": 9480.92,
"apr": 6.89,
"apr_nofees": 6.89,
"rv": 8385,
"term": 48,
"flat": 3.56,
"rv_interest": 1084.68,
"charges_ex_rv": 8396.24,
"fee_front": "0.00",
"fee_back": "1.00",
"fee_spread": 0,
"ref": 0,
"ho": 0,
"ho_a": 0,
"sb": 0,
"id": "25",
"product_name": "BNP PCP",
"excess_mileage": "7p"
}
]
}
}
}
},
"count": 2,
"taken": 443
}
}
try this
var jsonParsed = JObject.Parse(json);
var count = (int)jsonParsed["data"]["count"];
var taken = (int)jsonParsed["data"]["taken"];
((JObject)jsonParsed["data"]).Descendants()
.OfType<JProperty>()
.Where(attr => attr.Name == "count" || attr.Name == "taken")
.ToList()
.ForEach(attr => attr.Remove());
Data data = jsonParsed.ToObject<Data>();
data.count = count;
data.taken = taken;
classes
public class Data
{
public bool success { get; set; }
public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, Product[]>>>>> data { get; set; }
public int count { get; set; }
public int taken { get; set; }
public class Product
{
public int balance { get; set; }
public double first { get; set; }
public double regular { get; set; }
public double final { get; set; }
public double total { get; set; }
public double charges { get; set; }
public double apr { get; set; }
public double apr_nofees { get; set; }
public int term { get; set; }
public double flat { get; set; }
public string fee_front { get; set; }
public string fee_back { get; set; }
public int fee_spread { get; set; }
[JsonProperty("ref")]
public string refer { get; set; }
public int ho { get; set; }
public int ho_a { get; set; }
public int sb { get; set; }
public string id { get; set; }
public string product_name { get; set; }
public object excess_mileage { get; set; }
}

Deserializing object leads to null variables inside object

I am trying to deserialize a object in C#, using NewtonSoft framework fro json handling. This is my code.
Brief Explanation
Essentially, I am creating a api call to the login endpoint to authenticate my user (this works), I need to extract the bearer token from the api call which returns a UserResponseDTO, this DTO contains the AuthToken attribute which I need to access, to pass my test cases.
Now this is the code of my test case.
[Fact]
public async void SuccessfulGetUserDetails()
{
//Arrange
//Arrange
var content = JsonConvert.SerializeObject(success); //Prepare payload
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); //Set type to Json
//Act
var result = await _client.PostAsync("http://localhost:5000/api/Security/login", byteContent); //Send Request
var jsonstring = result.Content.ReadAsStringAsync().Result; //Get JSON String
UserResponseDTO dto = new UserResponseDTO();
dto = JsonConvert.DeserializeObject<UserResponseDTO>(jsonstring); //Deserialize
Assert.Equal(dto,null);
}
Now my last Assert check is to check if the DTO object is null....its not, but the values inside it are.
This is the UserResponseDTO
public class UserResponseDTO
{
public int UserId { get; set; }
public string AuthToken { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
public string Unit { get; set; }
public string IsActive { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public List<UserRole> UserRole { get; set; }
public List<Menus> Menus { get; set;}
}
public class UserRole
{
public Role Role { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public int ApplicationId { get; set; }
public string RoleDescription { get; set; }
public virtual List<RolePermission> RolePermission { get; set; }
public List<RoleMenu> RoleMenu { get; set; }
}
public class RoleMenu
{
public int RoleMenuId { get; set; }
public bool IsDefault { get; set; }
public virtual Menu Menu { get; set; }
}
public class RolePermission
{
public int RolePermissionId { get; set; }
public Permission Permission { get; set; }
}
public class Permission
{
public int PermissionId { get; set; }
public string Name { get; set; }
}
public class Menu
{
public int MenuId { get; set; }
public string Urlprefix { get; set; }
public string Url { get; set; }
public string Description { get; set; }
public bool IsParent { get; set; }
public bool IsActive { get; set; }
public int? ParentMenu { get; set; }
public string HtmlBody { get; set; }
public string CssClass { get; set; }
}
public class Menus
{
public bool isExternal { get; set; }
public string cssClass { get; set; }
public string routeLink { get; set; }
public string menuText { get; set; }
public List<SubMenuItems> subMenuItems { get; set; } = new List<SubMenuItems>();
}
public class SubMenuItems
{
public string routeLink { get; set; }
public string menuText { get; set; }
public string cssClass { get; set; }
}
Last but not least, I have noticed
THE CORRECT Json String is being returned however it is not being deserializd properly into a UserResponseDTO Object. And the values inside the DTO are all null.
What can I do to resolve this issue?
He is the JSON that is being returned in JSON String
Code of JSON as requested
"loginResponse": "Authenticated",
"userDetails": {
"userId": 3,
"authToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwibmJmIjoxNjIzMDM2OTkxLCJleHAiOjE2MjMwNDA1OTEsImlhdCI6MTYyMzAzNjk5MX0.wwIJ93syFnpcvjtw_Sj1s4uCtYPUtoROmwF3jkDZWo0",
"userName": "admin",
"fullName": "REDACTED",
"unit": null,
"isActive": "1",
"mobile": "+REDACTED",
"email": "REDACTED",
"userRole": [
{
"role": {
"roleId": 1,
"applicationId": 1,
"roleDescription": "Administrator",
"rolePermission": [
{
"rolePermissionId": 0,
"permission": {
"permissionId": 1,
"name": "CanApprove"
}
},
{
"rolePermissionId": 0,
"permission": {
"permissionId": 2,
"name": "CanReject"
}
},
{
"rolePermissionId": 0,
"permission": {
"permissionId": 3,
"name": "CanReview"
}
},
{
"rolePermissionId": 0,
"permission": {
"permissionId": 4,
"name": "CanDownload"
}
}
],
"roleMenu": [
{
"roleMenuId": 1,
"isDefault": true,
"menu": {
"menuId": 1,
"urlprefix": "UI",
"url": "worklist",
"description": "Menu",
"isParent": true,
"isActive": true,
"parentMenu": null,
"htmlBody": "<li><i class=\"fa fa-cog\"></i><span class=\"nav-label\">HEADING</span></li>",
"cssClass": "receipt"
}
},
{
"roleMenuId": 2,
"isDefault": false,
"menu": {
"menuId": 2,
"urlprefix": "UI",
"url": "reports",
"description": "Link 1",
"isParent": false,
"isActive": true,
"parentMenu": 1,
"htmlBody": "<li><i class=\"fa fa-plug\"></i><span class=\"nav-label\">HEADING</span></li>",
"cssClass": "fact_check"
}
},
{
"roleMenuId": 3,
"isDefault": false,
"menu": {
"menuId": 3,
"urlprefix": "UI",
"url": "generatefile",
"description": "Link 2",
"isParent": false,
"isActive": true,
"parentMenu": 1,
"htmlBody": "<li>HEADING</li>",
"cssClass": "file_present"
}
},
{
"roleMenuId": 9,
"isDefault": false,
"menu": {
"menuId": 4,
"urlprefix": "UI",
"url": "globalsearch",
"description": "Global Search",
"isParent": true,
"isActive": true,
"parentMenu": null,
"htmlBody": "<li>HEADING</li>",
"cssClass": "search"
}
}
]
}
}
],
"menus": [
{
"isExternal": false,
"cssClass": "receipt",
"routeLink": "worklist",
"menuText": "Menu",
"subMenuItems": [
{
"routeLink": "reports",
"menuText": "Link 1",
"cssClass": "fact_check"
},
{
"routeLink": "generatefile",
"menuText": "Link 2",
"cssClass": "file_present"
}
]
},
{
"isExternal": false,
"cssClass": "search",
"routeLink": "globalsearch",
"menuText": "Global Search",
"subMenuItems": []
}
]
}
}
Your json does not match the UserResponseDTO, you need add matched model like:
public class ResponseModel
{
public string LoginResponse { get; set; }
public UserResponseDTO UserDetails { get; set; }
}
If you do not want to add the response model, you need modify the json string to read userDetails:
//1. get the json string
string json = System.IO.File.ReadAllText("test.json");
//2. convert to JObject
var model = JObject.Parse(json);
//3. get userDetails json string
string jsonstring = model["userDetails"].ToString();
UserResponseDTO dto = new UserResponseDTO();
dto = JsonConvert.DeserializeObject<UserResponseDTO>(jsonstring);

How to get data from the given JSON format using JsonUtility in Unity using C#?

{
"page": 2,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 4,
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
"id": 5,
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
"id": 6,
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}
The above JSON was format I tried to test.So I added it to a string but it was showing errors.so I edited it to the following code removed double quotes and added single quotes now error was gone.Not sure to use single or double quotes.
string JSONDataString;
JSONDataString = #"{
'page': 2,
'per_page': 3,
'total': 12,
'total_pages': 4,
'data': [
{
'id': 4,
'first_name': 'Eve',
'last_name': 'last_name',
'avatar': 'https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg'
},
{
'id': 5,
'first_name': 'Charles',
'last_name': 'Morris',
'avatar': 'https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg'
},
{
'id': 6,
'first_name': 'Tracey',
'last_name': 'Ramos',
'avatar': 'https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg'
}
]
}";
I used a # at the start of the string.I do not know why I used it as I have seen in some examples.I removed all the double quotes and added single quotes.I created another class to handle the data from the JSON which is given below
public class DataHandler {
public int id;
public string firstname;
public string lastname;
public string avatar;
public DataHandler(int ID,string FName,string LName,string Avatar)
{
this.id = ID;
this.firstname = FName;
this.lastname = LName;
this.avatar = Avatar;
}
}
How to extract data from the first array and second array.First array elements means(page,per_page...total_pages) .Second array means(id,first_name,last_name,avatar from three groups)?
var obj = JsonUtility.FromJson<DataHandler>(JSONDataString);
The class representing the JSON is wrong.
See the correct representation below:
public class Datum
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
public class RootObject
{
public int page { get; set; }
public int per_page { get; set; }
public int total { get; set; }
public int total_pages { get; set; }
public List<Datum> data { get; set; }
}
Don't forget to mark your class as serializable.
Use the attribute:
[System.Serializable]
Usage
RootObject root=JsonUtility.FromJson<RootObject>(jsonString);
foreach(var item in root.data){
Debug.Log(item.id);
}
Your class that represent object is not right. You can generate a class from json in the visual studio "Edit > Paste special > Paste JSON as Classes".
In you case it's:
public class Rootobject
{
public int page { get; set; }
public int per_page { get; set; }
public int total { get; set; }
public int total_pages { get; set; }
public Datum[] data { get; set; }
}
public class Datum
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
Your "JSONDataString" json string looks good so just use "Newtonsoft.Json" nuget to parse the object:
var data = JsonConvert.DeserializeObject<Rootobject>(json);

C# Parse Json with multiple objects and arrays newtonsoft

I'm attempting to parse a rather convoluted/unnecessarily complicated JSON output using newtonsoft in C# however for some reason my parser always returns null. I have searched all over SO and cant't seem to find a solution.
An example of a JSON file I'm trying to parse:
{
"success": 1,
"d": {
"gameData": {
"MJ2Y7tDg": {
"scores": [
{
"max": 1.83,
"avg": 1.73,
"rest": 2,
"active": true,
"scoreid": "2c556xv464x0x4vtqc"
},
{
"max": 3.47,
"avg": 3.24,
"rest": 2,
"active": true,
"scoreid": "2c556xv498x0x0"
},
{
"max": 6.06,
"avg": 5.08,
"rest": 1,
"active": true,
"scoreid": "2c556xv464x0x4vtqd"
}
],
"count": 62,
"highlight": [
false,
true
]
},
"jZICYUQu": {
"scores": [
{
"max": 2.25,
"avg": 2.13,
"rest": null,
"active": true,
"scoreid": "2c5guxv464x0x4vuiv"
},
{
"max": 3.55,
"avg": 3.29,
"rest": null,
"active": true,
"scoreid": "2c5guxv498x0x0"
},
{
"max": 3.9,
"avg": 3.33,
"rest": null,
"active": true,
"scoreid": "2c5guxv464x0x4vuj0"
}
],
"count": 62,
"highlight": [
false,
false
]
}
}
}
}
This is what i have so far, I am very new to JSON wrangling :)
public class RootObject
{
public int success { get; set; }
public List<d> d { get; set; }
}
public class d
{
public List<gameData> gameData { get; set; }
}
public class gameData
{
public IDictionary<string, Score> gameData{ get; set; }
public List<scores[]> GameList;
}
public class Score
{
public double max { get; set; }
public double avg { get; set; }
public int rest { get; set; }
public bool active { get; set; }
public string scoreid { get; set; }
}
Anyone with more JSON wrangling experience know how to get this working?
Thankyou in advanced.
P.S I am currently in high school, learning C#
The parser returns null because structure of your classes doesn't correctly resemble the structure of JSON. The correct structure of classes would be:
public class RootObject
{
public int success { get; set; }
public Class_d d { get; set; }
}
public class Class_d
{
public Dictionary<string, GameData> gameData { get; set; }
}
public class GameData
{
public List<Score> scores { get; set; }
public int count { get; set; }
public bool[] highlight { get; set; }
}
public class Score
{
public decimal max { get; set; }
public decimal avg { get; set; }
public int? rest { get; set; }
public bool active { get; set; }
public string scoreid { get; set; }
}
and you can use it as follows:
string json = "..."; // the JSON in your example
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);

Categories

Resources