Converting json's array field to list - c#

public List<Movie> getPopularMovies()
{
List<Movie> movies = null;
var client = new HttpClient();
var task = client.GetAsync(url)
.ContinueWith((taskwithresponse) =>
{
var response = taskwithresponse.Result;
var jsonString = response.Content.ReadAsStringAsync();
jsonString.Wait();
movies = JsonConvert.DeserializeObject<List<Movie>>(jsonString.Result);
});
task.Wait();
return movies;
}
Json to convert
{
"page": 1,
"results": [
{
"poster_path": "/xfWac8MTYDxujaxgPVcRD9yZaul.jpg",
"adult": false,
"overview": "After his career is destroyed, a brilliant but arrogant surgeon gets a new lease on life when a sorcerer takes him under his wing and trains him to defend the world against evil.",
"release_date": "2016-10-25",
"genre_ids": [
28,
12,
14,
878
],
"id": 284052,
"original_title": "Doctor Strange",
"original_language": "en",
"title": "Doctor Strange",
"backdrop_path": "/hETu6AxKsWAS42tw8eXgLUgn4Lo.jpg",
"popularity": 55.113822,
"vote_count": 598,
"video": false,
"vote_average": 6.99
}
],
"total_results": 19676,
"total_pages": 984
}
I'd like to set movies as results array. My solution (what I found here) is about setting movies as the whole json (pagem results, total_results, total_pages). In fact the json answer is a single object.
How to get deeply inside this json (while converting) to set the List<Movie> movies to results array?

Create a class for the entire response, with a list of movies on it.
response = JsonConvert.DeserializeObject<JsonResponse>(jsonString.Result);
movies = response.Movies;
Example classes:
public class JsonResponse {
[JsonProperty("results")]
public List<Movie> Movies { get; set; }
[JsonProperty("page")]
public int Page { get; set; }
[JsonProperty("total_results")]
public int TotalResults { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
}
public class Movie
{
[JsonProperty("poster_path")]
public string PosterPath { get; set; }
[JsonProperty("adult")]
public bool Adule { get; set; }
[JsonProperty("overview")]
public string Overview { get; set; }
[JsonProperty("release_date")]
public string ReleaseDate { get; set; }
[JsonProperty("genre_ids")]
public List<int> GenreIds { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("original_title")]
public string OriginalTitle { get; set; }
[JsonProperty("original_language")]
public string OriginalLanguage { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("backdrop_path")]
public string BackdropPath { get; set; }
[JsonProperty("popularity")]
public double Popularity { get; set; }
[JsonProperty("vote_count")]
public int VoteCount { get; set; }
[JsonProperty("video")]
public bool Video { get; set; }
[JsonProperty("vote_average")]
public double VoteAverage { get; set; }
}

Related

how can I preserve this json format, while adding to it before serializing it?

I have a fairly complex json file I am deserializing into a datatable to be displayed to datgridview.
when it comes in the json file has alot of values and properties in it.
i add about 5-6 properties to it myself for manipulation in my software. When I am all done with my software here I want to serialize this datatable back to json. but with the added properties.
problem is I finally figured out how to serialize my properties back to the file, and realized that in the process I dont serialize all the other fields back in it seems. there are dozens of them and they are nested. I'm not to sure how to get all the nested info into a datatable.
can anyone explain or help me pack all this info into my datatable?
below will be some code snips to show my process so far.
Here is main event
this is where I deserialize the file and load to datagridview.
public void MainForm_Load(object sender, EventArgs e)
{
var loadscreen = new SplashScreen();
loadscreen.Show();
//double buffer fixes latency when scrolling thru datagridviews
toolDataGridView.GetType().GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.Instance |
BindingFlags.NonPublic).SetValue(toolDataGridView, true,
null);
//json file holding all data to be parsed for tool list.
string myDynamicJSON = File.ReadAllText(#"testLibrary.json");
//object with json data in it
ToolJson ToolData = JsonConvert.DeserializeObject<ToolJson>(myDynamicJSON);
//DataTable with something in it, do the binding
BindingSource SBind = new BindingSource
{
DataSource = tooldataSet.Tables["Tool"]
};
//looks into File finds json fields, and assign them to variables to be used in C# to
create the rows.
foreach (var datum in ToolData.datum)
{
string description = datum.Description;
string vendor = datum.Vendor;
double cost = datum.Cost;
string serial = datum.ProductLink;
string employee = datum.employee;
string location = datum.location;
bool returntool = datum.returnTool;
int onHand = datum.onHandQty;
int stockQty = datum.stockQty;
int orderQty = ToolData.Order(datum.stockQty, datum.onHandQty); //stockQty -
onHand = orderQty, if value is less than 0, set the value of orderQty to 0.
string toolType = datum.Type;
double diameter = datum.Geometry.Dc;
double OAL = datum.Geometry.Oal;
string productID = datum.ProductId;
//Populate the DataTable with rows of data
DataRow dr = tooldataSet.Tool.NewRow();
// Fill the values
dr["Description"] = description;
dr["Vendor"] = vendor;
dr["Cost"] = cost;
dr["Serial #"] = serial;
dr["Employee"] = employee;
dr["Location"] = location;
dr["OnHand"] = onHand;
dr["StockQty"] = stockQty;
dr["OrderQty"] = orderQty;
dr["Return"] = returntool;
dr["Diameter"] = diameter;
dr["OAL"] = OAL;
dr["Type"] = toolType;
dr["Product Id"] = productID;
//once all data is added to the row, add the row, and loop untill all data is
loaded.
tooldataSet.Tool.Rows.Add(dr);
}
toolDataGridView.RowHeadersWidthSizeMode =
DataGridViewRowHeadersWidthSizeMode.DisableResizing;
toolDataGridView.RowHeadersVisible = false;
//bind our dataset.table to the gridview
toolDataGridView.DataSource = SBind;
toolDataGridView.RowHeadersWidthSizeMode =
DataGridViewRowHeadersWidthSizeMode.EnableResizing;
toolDataGridView.RowHeadersVisible = true;
//fills drop down employee list with names from the text file
PopulateList(#"EmployeeList.txt");
//hide splashscreen once Gridview has loaded the data
loadscreen.Hide();
}
Here is simple button click event to trigger the serializing back to the file
private void button1_Click(object sender, EventArgs e)
{
BindingSource SBind = new BindingSource
{
DataSource = tooldataSet.Tables["Tool"]
};
toolDataGridView.DataSource = SBind;
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(tooldataSet.Tool,
Formatting.Indented);
System.IO.File.WriteAllText(#"testLibrary.json", serialized);
}
And finally here is a snippet of the json file, this is only 1 item in the list of hundreds
{
"data": [
{
"BMC": "carbide",
"Cost": 52.68,
"Employee": "",
"GRADE": "Mill Generic",
"Location": "",
"description": "5/8-11\"",
"geometry": {
"CSP": false,
"DC": 0.433,
"HAND": true,
"LB": 2,
"LCF": 0.5,
"NOF": 4,
"NT": 1,
"OAL": 5,
"SFDM": 0.625,
"TP": 0.0909091,
"shoulder-length": 1.969,
"thread-profile-angle": 60
},
"guid": "0112c196-8a79-421d-8dda-d4aa964aa6d7",
"holder": {
"description": "Maritool CAT40-ER32-2.35",
"guid": "e800051b-e2d6-4699-a2b6-dad6466a0a0c",
"last_modified": 1485790626152,
"product-id": "CAT40-ER32-2.35",
"product-link": "",
"segments": [
{
"height": 0.148,
"lower-diameter": 1.5,
"upper-diameter": 1.97
},
{
"height": 0.836,
"lower-diameter": 1.97,
"upper-diameter": 1.97
}
],
"type": "holder",
"unit": "inches",
"vendor": "Maritool"
},
"onHandQty": 3,
"post-process": {
"break-control": false,
"comment": "",
"diameter-offset": 17,
"length-offset": 17,
"live": true,
"manual-tool-change": false,
"number": 17,
"turret": 0
},
"product-id": "GMDTTM58-11UN4FL",
"product-link": "6010",
"start-values": {
"presets": [
{
"description": "",
"f_n": 0.012091641057817,
"f_z": 0.0031,
"guid": "b118ce46-da35-4ed6-9806-b98e05ffe077",
"n": 2646.45632854884,
"n_ramp": 2646,
"name": "Tool Steel",
"tool-coolant": "flood",
"use-stepdown": false,
"use-stepover": false,
"v_c": 300,
"v_f": 32.8160584740056,
"v_f_leadIn": 32,
"v_f_leadOut": 32,
"v_f_plunge": 32,
"v_f_ramp": 32
},
{
"description": "",
"f_n": 0.01118476797848,
"f_z": 0.0028,
"guid": "0e1767f5-b0ef-422f-b49d-6cb8c3eb06ed",
"n": 3308.0704106860494,
"n_ramp": 3308,
"name": "Stainless Steel",
"tool-coolant": "flood",
"use-stepdown": false,
"use-stepover": false,
"v_c": 375,
"v_f": 37.0503885996837,
"v_f_leadIn": 37,
"v_f_leadOut": 37,
"v_f_plunge": 37,
"v_f_ramp": 37
}
]
},
"stockQty": 5,
"type": "thread mill",
"unit": "inches",
"vendor": "Gorilla Mill"
}
]
}
EDIT
Figured I should add in what my result is right now if I click m button
[
{
"Description": "5/8-11\"",
"Cost": 0.0,
"Vendor Item Number": null,
"Vendor Item": null,
"Serial #": "6010",
"Source": null,
"Description3": null,
"Description2": null,
"LastInventory": null,
"Last Price": null,
"DC": "0.433",
"OAL": "5",
"GUID": "0112c196-8a79-421d-8dda-d4aa964aa6d7",
"Product Id": null,
"Type": "thread mill",
"OnHandQty": 0,
"StockQty": 0,
"OrderQty": 0,
"Return": false,
"Employee": "",
"Vendor": "Gorilla Mill",
"Location": "",
"Grade": "Mill Generic",
"BMC": "Carbide",
"start-values": "QuickType.StartValues",
"unit": "Inches",
"geometry": "QuickType.Geometry",
"CSP": "False",
"HAND": "True",
"LB": "2",
"LCF": "0.5",
"NOF": "4",
"NT": "1",
"SFDM": "0.625",
"TP": "0",
"shoulder-length": "1.969",
"thread-profile-angle": "60",
"SIG": "0",
"RE": "0",
"TA": "0",
"tip-diameter": "0",
"tip-length": "0",
"break-control": "False",
"comment": "",
"diameter offset": "17",
"length offset": "17",
"live": "True",
"manual tool change": "False",
"number": "17",
"turret": "0",
"presets": "QuickType.Preset[]",
"holder": "QuickType.Holder",
"post-process": "QuickType.PostProcess",
"Diameter": null,
"last_modified": null,
"product-id": "GMDTTM58-11UN4FL",
"product-link": null,
"segments": null
}
]
Also to note I got my class using quicktype.io online, so the class can handle the entire file no problem(I would assume)
EDIT AGAIN
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class ToolJson
{
[JsonProperty("data")]
public List<Datum> datum { get; set; }
[JsonProperty("version")]
public long Version { get; set; }
public int Order(int stockQty, int onHandQty)
{
int orderQty = stockQty - onHandQty;
if (orderQty < 0)
{
orderQty = 0;
}
return orderQty;
}
}
public partial class Datum
{
[JsonProperty("BMC")]
public Bmc Bmc { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("GRADE")]
public string Grade { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
[JsonProperty("guid")]
public string Guid { get; set; }
[JsonProperty("holder")]
public Holder holder { get; set; }
[JsonProperty("post-process")]
public PostProcess PostProcess { get; set; }
[JsonProperty("product-id")]
public string ProductId { get; set; }
[JsonProperty("product-link")]
public string ProductLink { get; set; }
[JsonProperty("start-values")]
public StartValues StartValues { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("unit")]
public Unit Unit { get; set; }
[JsonProperty("vendor")]
public string Vendor { get; set; }
[JsonProperty("Cost")]
public double Cost { get; set; }
[JsonProperty("Employee")]
public string employee { get; set; }
[JsonProperty("Location")]
public string location { get; set; }
[JsonProperty("onHandQty")]
public int onHandQty { get; set; }
[JsonProperty("stockQty")]
public int stockQty { get; set; }
[JsonProperty("orderQty")]
public int orderQty { get; set; }
[JsonProperty("ReturnTool")]
public bool returnTool { get; set; }
}
public partial class Geometry
{
[JsonProperty("CSP")]
public bool Csp { get; set; }
[JsonProperty("DC")]
public double Dc { get; set; }
[JsonProperty("HAND")]
public bool Hand { get; set; }
[JsonProperty("LB")]
public double Lb { get; set; }
[JsonProperty("LCF")]
public double Lcf { get; set; }
[JsonProperty("NOF")]
public long Nof { get; set; }
[JsonProperty("NT")]
public long Nt { get; set; }
[JsonProperty("OAL")]
public double Oal { get; set; }
[JsonProperty("SFDM")]
public double Sfdm { get; set; }
[JsonProperty("TP")]
public double Tp { get; set; }
[JsonProperty("shoulder-length")]
public double ShoulderLength { get; set; }
[JsonProperty("thread-profile-angle")]
public long ThreadProfileAngle { get; set; }
[JsonProperty("SIG")]
public long Sig { get; set; }
[JsonProperty("RE")]
public double Re { get; set; }
[JsonProperty("TA")]
public long Ta { get; set; }
[JsonProperty("tip-diameter")]
public double TipDiameter { get; set; }
[JsonProperty("tip-length")]
public double TipLength { get; set; }
}
public partial class Holder
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("guid")]
public string Guid { get; set; }
[JsonProperty("last_modified")]
public string LastModified { get; set; }
[JsonProperty("product-id")]
public string ProductId { get; set; }
[JsonProperty("product-link")]
public string ProductLink { get; set; }
[JsonProperty("segments")]
public Segment[] Segments { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("unit")]
public string Unit { get; set; }
[JsonProperty("vendor")]
public string Vendor { get; set; }
}
public partial class Segment
{
[JsonProperty("height")]
public double Height { get; set; }
[JsonProperty("lower-diameter")]
public double LowerDiameter { get; set; }
[JsonProperty("upper-diameter")]
public double UpperDiameter { get; set; }
}
public partial class PostProcess
{
[JsonProperty("break-control")]
public bool BreakControl { get; set; }
[JsonProperty("comment")]
public string Comment { get; set; }
[JsonProperty("diameter-offset")]
public long DiameterOffset { get; set; }
[JsonProperty("length-offset")]
public long LengthOffset { get; set; }
[JsonProperty("live")]
public bool Live { get; set; }
[JsonProperty("manual-tool-change")]
public bool ManualToolChange { get; set; }
[JsonProperty("number")]
public long Number { get; set; }
[JsonProperty("turret")]
public long Turret { get; set; }
}
public partial class StartValues
{
[JsonProperty("presets")]
public Preset[] Presets { get; set; }
}
public partial class Preset
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("f_n")]
public double? FN { get; set; }
[JsonProperty("f_z")]
public double? FZ { get; set; }
[JsonProperty("guid")]
public Guid Guid { get; set; }
[JsonProperty("n")]
public double N { get; set; }
[JsonProperty("n_ramp")]
public double? NRamp { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("tool-coolant")]
public ToolCoolant ToolCoolant { get; set; }
[JsonProperty("use-stepdown")]
public bool UseStepdown { get; set; }
[JsonProperty("use-stepover")]
public bool UseStepover { get; set; }
[JsonProperty("v_c")]
public double VC { get; set; }
[JsonProperty("v_f")]
public double? VF { get; set; }
[JsonProperty("v_f_leadIn")]
public double? VFLeadIn { get; set; }
[JsonProperty("v_f_leadOut")]
public double VFLeadOut { get; set; }
[JsonProperty("v_f_plunge")]
public double VFPlunge { get; set; }
[JsonProperty("v_f_ramp")]
public double VFRamp { get; set; }
[JsonProperty("v_f_retract")]
public double VFRetract { get; set; }
[JsonProperty("stepdown")]
public double Stepdown { get; set; }
[JsonProperty("stepover")]
public double Stepover { get; set; }
}
public enum Bmc { Carbide, Hss };
public enum Grade { Generic, MillGeneric };
public enum Description { LongHolder, MaritoolCat40Er32235 };
public enum ProductId { Cat40Er32235, Empty };
public enum TypeEnum { Holder };
public enum Unit { Inches, Millimeters };
public enum Vendor { Empty, Maritool };
public enum ToolCoolant { Disabled, Flood };
Latest Edit
the following code will deser and then set the object to the DGV. other than this small bit of code there isn't much else I have to load the content.
var v = JsonConvert.DeserializeObject<ToolJson>
(File.ReadAllText(#"testLibrary.json"));
//set DGV source to our datums
toolDataGridView.DataSource = v.Datums.Cast<IInteresting>
().ToList();
Newest Edit
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft;
using Newtonsoft.Json;
namespace QuickType
{
public interface IInteresting
{
//adding below creates the columns for our DGV
string ProductLink {get;set;}
string Type { get; set; }
string Description { get; set; }
string Vendor { get; set; }
double GeometryDc { get; set; }
double GeometryOal { get; set; }
double Cost { get; set; }
int onHandQty { get; set; }
int OrderQty { get; set; }
int stockQty { get; set; }
string location { get; set; }
string employee { get; set; }
}
public partial class Datum : IInteresting
{
//top level props in datum
public int OrderQty { get; set; }
[JsonProperty("product-link")]
public string ProductLink { get; set; }
[JsonProperty("Cost")]
public double Cost { get; set; }
[JsonProperty("Employee")]
public string employee { get; set; }
[JsonProperty("Location")]
public string location { get; set; }
[JsonProperty("onHandQty")]
public int onHandQty { get; set; }
[JsonProperty("stockQty")]
public int stockQty { get; set; }
[JsonProperty("orderQty")]
public int orderQty { get; set; }
[JsonProperty("ReturnTool")]
public bool returnTool { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("vendor")]
public string Vendor { get; set; }
[JsonProperty("product-id")]
public string ProductId { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
//below are the props that are nested, we need to pull them out of
the nest
[JsonIgnore]
public double GeometryDc
{
get => this.Geometry.Dc;
set => this.Geometry.Dc = value;
}
[JsonIgnore]
public double GeometryOal
{
get => this.Geometry.Oal;
set => this.Geometry.Oal = value;
}
}
}
Edit including Serialization
the button click event below, should simulate what should happen when the user closes the form. button click instead for testing.
what happens is it serializes, but its not in the correct format.
private void button2_Click(object sender, EventArgs e)
{
File.WriteAllText(#"C:\Users\User\OneDrive - Motion
Controls Robotics, Inc\Desktop\test
inventory\testLibrary1.json",
JsonConvert.SerializeObject(toolDataGridView.DataSource,
Formatting.Indented));
}
Add this somewhere, in another class:
public interface IInteresting
{
string Description { get; set; }
double GeometryDc { get; set; }
double GeometryOal { get; set; }
}
public partial class Datum : IInteresting
{
[JsonIgnore]
public double GeometryDc {
get => this.Geometry.Dc;
set => this.Geometry.Dc = value;
}
[JsonIgnore]
public double GeometryOal
{
get => this.Geometry.Oal;
set => this.Geometry.Oal = value;
}
}
This is just a fragment; you can fill in the other props later. I have deomnstrated an interface that has 3 props. One is a straight up a property of Datum already (Description). The other two are props that dig out nested data; they need implementing, like I showed, including the JsonIgnore tag. Your remaining props are likely to be similar to either the first case (already a prop of Datum, just needs mentioning in interface) or a nested data (needs a new name inventing in interface and a new code putting to dig it out of the hierarchy)
Then put this code behind in a new form called Form1 that contain a DataGridView1 and a Button1 (in the designer):
public Form1(string s1 = null)
{
InitializeComponent();
var v = JsonConvert.DeserializeObject<ToolJson>(File.ReadAllText("textfile1.json"));
//note I renamed your `datum` property to `Datums`
dataGridView1.DataSource = v.Datums.Cast<IInteresting>().ToList();
}
private void button1_Click(object sender, EventArgs e)
{
var x = JsonConvert.SerializeObject(dataGridView1.DataSource);
} //put a breakpoint on this line
The datagridview gets a list of IInteresting, and it only makes columns for props on an IInteresting, so in this case I see 3 columns (3 props):
Edit some data
Click the button. The datasource of the grid (it contains all the data, not just the visible ones) is serialized and the output contains all the data
Adding new data, not already present in the json:
public interface IInteresting
{
string Description { get; set; }
double GeometryDc { get; set; }
double GeometryOal { get; set; }
string DatumXxNew {get; set;}
string GeometryXxNew {get; set;}
}
public partial class Datum : IInteresting
{
[JsonIgnore]
public double GeometryDc {
get => this.Geometry.Dc;
set => this.Geometry.Dc = value;
}
[JsonIgnore]
public double GeometryOal
{
get => this.Geometry.Oal;
set => this.Geometry.Oal = value;
}
//do not JsonIgnore
public string DatumXxNew {get; set;}
//DO JsonIgnore this one, but NOT the one it links to
[JsonIgnore]
public string GeometryXxNew {
get => this.Geometry.XxNew;
set => this.Geometry.XxNew = value;
}
}
public partial class Geometry{
//do not JsonIgnore
public string XxNew {get;set;}
}

Pass Nested Deserialized JSON from Controller to View

After using HttpClient class to convert my JSON to a string and deserialize it with
var response = Res.Content.ReadAsStringAsync().Result;
data = JsonConvert.DeserializeObject<List<Employee>>(response);
How do I pass the data that I receive in the Controller from the call using the Model below to the View?
public class RuleType
{
public int Id { get; set; }
public string Description { get; set; }
public bool Inactive { get; set; }
}
public class RuleCategory
{
public int Id { get; set; }
public string Description { get; set; }
public bool Inactive { get; set; }
}
public class Employee
{
public string Description { get; set; }
public object EndDateTime { get; set; }
public int Id { get; set; }
public bool Inactive { get; set; }
public int RuleAction { get; set; }
public DateTime StartDateTime { get; set; }
public RuleType RuleType { get; set; }
public RuleCategory RuleCategory { get; set; }
}
Here is one object from the call
[
{
"Description": "Test Description",
"EndDateTime": null,
"Id": 1,
"Inactive": false,
"RuleAction": -2,
"StartDateTime": "2017-01-06T14:58:58Z",
"RuleType": {
"Id": 6,
"Description": "Test Description",
"Inactive": false
},
"RuleCategory": {
"Id": 1,
"Description": "Description",
"Inactive": false
}
}
]
Not sure if I'm missing something, but if you have an object you want to return to the view from the controller, you simply:
return View(viewModel); // in your case viewModel = 'data'
As others have said here already, you should be deserializing the JSON into a RootObject instead of an Employee like so:
var response = Res.Content.ReadAsStringAsync().Result;
var data = JsonConvert.DeserializeObject<List<RootObject>>(response);
You can then pass the model into the view using just:
return View(data)
You should also consider renaming RootObject into something more useful (such as employee?) as RootObject is not a very useful or descriptive name.

Change existing JSON message format into new with fields in C#?

We have to do some changes in existing JSON response and it requires to modify existing c# code too. Till now I've tried but don't get the exact idea about the formatting as it is new for me.
Can any one please check and suggest the changes in below code?
Existing JSON message:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_type": {
"standard": [
5
],
"custom": []
},
"extra_bed_type": {
"standard": [
5
],
"custom": []
},
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
In above JSON message we have to replace the "bed_type" and "extra_bed_type" with "bed_configurations" and "extra_bed_configurations" in below newly provided format by client:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_configurations": [
[{
"type": "standard",
"code": 3,
"count": 1
}],
[{
"type": "standard",
"code": 1,
"count": 2
}]
],
"extra_bed_configurations": [
[{
"type": "standard",
"code": 900302,
"count": 1
},
{
"type": "custom",
"name": "Rollaway with wheel locks and adjustable height",
"count": 1
}]
],
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
Existing C# code to generate the JSON response message format:
public class HotelRoomType
{
public string code { get; set; }
public string name { get; set; }
public string description { get; set; }
public List<Photo> photos { get; set; }
public Amenities room_amenities { get; set; }
public string room_size { get; set; }
public string room_size_units { get; set; }
public BedType bed_type { get; set; }
public BedType extra_bed_type { get; set; }
public RoomViewType room_view_type { get; set; }
public string accessibility { get; set; }
public MaxOccupancy max_occupancy { get; set; }
public string room_smoking_policy { get; set; }
}
Below is the code to fill the data in required fields of JSON message its inside a method which contains lines of code so I get it separately:
HotelRoomType hotelrmtype = new HotelRoomType();
hotelrmtype.bed_type = Common.GetStandardBedTypeMappingID(rm.BedType);
if (rm.NumOfBed > 1)
hotelrmtype.extra_bed_type = hotelrmtype.bed_type; //same as bed type
hotelrmtypeDict.Add(rm.Code, hotelrmtype); //Binding Data into Dictionary.
GetStandardBedTypeMappingID() contains :
public static CRS.TripConnect.BedType GetStandardBedTypeMappingID(short code)
{
CRS.TripConnect.BedType tripConnectBedType = new CRS.TripConnect.BedType();
List<int> standardBedTypes = new List<int>();
List<object> customBedTypes = new List<object>();
tripConnectBedType.standard = standardBedTypes;
tripConnectBedType.custom = customBedTypes; //These is blank.
short id = 0;
switch (code)
{
case 10:
id = 3;
break;
case 20: // 20 Queen Q 5
id = 5;
break;
case 30: // 30 Double D 1
id = 1;
break;
case 40: // 40 Twin T 8
id = 8;
break;
}
standardBedTypes.Add(id);
return tripConnectBedType;
}
Update: With the help of #Sam Answer below I have modified the code:
public class HotelRoomType
{
//Added following properties
public List<List<Bed_Configurations>> bed_configurations { get; set; }
public List<List<Extra_Bed_Configurations>> extra_bed_configurations { get; set; }
}
Created two new classes as:
public class Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
public class Extra_Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
public string name { get; set; }
}
Now the question is: How to fill these two list?
I'm trying to achieve this like below but it is giving me conversion error.
Bed_Configurations bdConfig = new Bed_Configurations();
bdConfig.type = "Standard";
bdConfig.code = Common.GetStandardBedTypeMappingIDnew(rm.BedType);
bdConfig.count = rm.NumOfBed;
hotelrmtype.bed_configurations.Add(bdConfig);
Error Message:
Please Advise the changes in the above code so as to get the required JSON message. Appreciate your help!
public class RootClass
{
public HotelRoomType hotel_room_types { get; set; }
}
public class HotelRoomType
{
public BedModelAndDetails QUEEN { get;set; }
}
public class BedModelAndDetails
{
public string accessibility { get; set; }
public string room_smoking_policy { get; set; }
public string code { get; set; }
//public BedType bed_type { get; set; }
public object bed_type { get; set; }
//public BedType extra_bed_type { get; set; }
public object extra_bed_type { get; set; }
public List<List<BedConfiguration>> bed_configurations { get; set; }
public List<List<BedConfiguration>> extra_bed_configurations { get; set; }
}
public class BedType
{
public List<int> standard { get; set; }
public List<int> custom { get; set; }
}
public class BedConfiguration
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
[TestMethod]
public void ReplaceJson()
{
var inputJson1 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\", \"bed_type\": {\"standard\": [5],\"custom\": [] }, \"extra_bed_type\": { \"standard\": [5], \"custom\": [] },\"accessibility\": \"compliant_with_local_laws_for_disabled\", \"room_smoking_policy\": \"non_smoking\" } " +"}}";
var input1 = JsonConvert.DeserializeObject<RootClass>(inputJson1, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
var inputJson2 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\",\"bed_configurations\": [[{\"type\": \"standard\",\"code\": 3,\"count\": 1}],[{\"type\": \"standard\",\"code\": 1,\"count\": 2}]],\"extra_bed_configurations\": [[{\"type\": \"standard\",\"code\": 900302,\"count\": 1},{\"type\": \"custom\",\"name\": \"Rollaway with wheel locks and adjustable height\",\"count\": 1}]],\"accessibility\": \"compliant_with_local_laws_for_disabled\",\"room_smoking_policy\": \"non_smoking\"} }}";
var input2 = JsonConvert.DeserializeObject<RootClass>(inputJson2);
//var finalInput = new RootClass();
//finalInput.hotel_room_types = inputJson1
//input1.hotel_room_types.QUEEN.bed_configurations = input2.hotel_room_types.QUEEN.bed_configurations;
//input1.hotel_room_types.QUEEN.extra_bed_configurations = input2.hotel_room_types.QUEEN.extra_bed_configurations;
input1.hotel_room_types.QUEEN.bed_type = input2.hotel_room_types.QUEEN.bed_configurations;
input1.hotel_room_types.QUEEN.extra_bed_type = input2.hotel_room_types.QUEEN.extra_bed_configurations;
}
Does this help?

Json.Net deserialize JSON objects with index as name [duplicate]

This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Closed 8 years ago.
I am attempting to parse JSON from a web service using Json.NET, the web service returns data in the following format:
{
"0": {
"ID": 193,
"Title": "Title 193",
"Description": "Description 193",
"Order": 5,
"Hyperlink": "http://someurl.com"
},
"1": {
"ID": 228,
"Title": "Title 228",
"Description": "Description 228",
"Order": 4,
"Hyperlink": "http://someurl.com"
},
"2": {
"ID": 234,
"Title": "Title 234",
"Description": "Description 234",
"Order": 3,
"Hyperlink": "http://someurl.com"
}
}
I used json2sharp to generate a class from the JSON:
public class __invalid_type__0
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__1
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__2
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class RootObject
{
public __invalid_type__0 __invalid_name__0 { get; set; }
public __invalid_type__1 __invalid_name__1 { get; set; }
public __invalid_type__2 __invalid_name__2 { get; set; }
}
I then cleaned up the class and was left with the following:
public class Articles
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class FeaturedArticles
{
public List<Articles> articles { get; set; }
}
When I attempt to load the data into my singleton for use in the app:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
_featuredArticles = JsonConvert.DeserializeObject<FeaturedArticles> (response.Content);
foreach (Articles a in _featuredArticles.Articles)
Console.WriteLine (a.Title);
}
I find that the Articles do not get deserialized.
I've verified that the JSON data is returned from the web service. I believe the issue exists in the structure of my JSON feed, where each item returned from the feed is given a name which equals the index the item is being returned as.
I am new to using Json.NET so I'm not sure how I should proceed; I cannot change the structure of the JSON feed but need to consume it's data. Anyone have any recommendations?
You don't need FeaturedArticles class, you can deserialize the JSON into a Dictionary<string, Articles> like this:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
Dictionary<string, Articles> _featuredArticles = JsonConvert.DeserializeObject<Dictionary<string, Articles>>(response.Content);
foreach (string key in _featuredArticles.Keys)
{
Console.WriteLine(_featuredArticles[key].Title);
}
}
Demo: https://dotnetfiddle.net/ZE1BMl

Reading the content of a json string

So im doing a HttpWebRequest which returns a jsonstring. The deserialized string looks like this:
{
"have_warnings": "20",
"pp_active": false,
"noofslots": 2,
"paused": true,
"pause_int": "0",
"mbleft": 7071.03378,
"diskspace2": 55.610168,
"diskspace1": 55.610168,
"jobs": [{
"timeleft": "0:00:00",
"mb": 6918.785553,
"msgid": "",
"filename": "xxxx",
"mbleft": 5869.015694,
"id": "xx"
},
{
"timeleft": "0:00:00",
"mb": 2238.526516,
"msgid": "",
"filename": "xxxx",
"mbleft": 1202.018086,
"id": "xxxx"
}],
"speed": "0 ",
"timeleft": "0:00:00",
"mb": 9157.312069,
"state": "Paused",
"loadavg": "0.11 | 0.08 | 0.08 | V=444M R=88M",
"kbpersec": 0.0
}
Now I want to display some of the data in a labels in my UI. What would be the best way to do this?
I tryed:
dynamic array = JsonConvert.DeserializeObject(qstatusOutput);
foreach (var item in array)
{
MessageBox.Show("{0}{1}", item.timeleft, item.mbleft);
}
But I get a error
'Newtonsoft.Json.Linq.JProperty' does not contain a definition for
'timeleft'
To take a type-safe approach you can use this site: http://json2csharp.com/
var root = JsonConvert.DeserializeObject<RootObject>(qstatusOutput);
foreach (var job in root.jobs)
{
Console.WriteLine(job.timeleft);
}
public class Job
{
public string timeleft { get; set; }
public double mb { get; set; }
public string msgid { get; set; }
public string filename { get; set; }
public double mbleft { get; set; }
public string id { get; set; }
}
public class RootObject
{
public string have_warnings { get; set; }
public bool pp_active { get; set; }
public int noofslots { get; set; }
public bool paused { get; set; }
public string pause_int { get; set; }
public double mbleft { get; set; }
public double diskspace2 { get; set; }
public double diskspace1 { get; set; }
public List<Job> jobs { get; set; }
public string speed { get; set; }
public string timeleft { get; set; }
public double mb { get; set; }
public string state { get; set; }
public string loadavg { get; set; }
public double kbpersec { get; set; }
}
but if you want to use dynamic then
dynamic array = JsonConvert.DeserializeObject(qstatusOutput);
foreach (var item in array.jobs)
{
MessageBox.Show(String.Format("{0} {1}", item.timeleft, item.mbleft));
}
time left is inside jobs so try below
foreach (var item in array.jobs)
{
MessageBox.Show("{0}{1}", item.timeleft, item.mbleft);
}
Your results from DeserializeObject is not the array. It's a structure that contains the array as one property.
dynamic result = JsonConvert.DeserializeObject(qstatusOutput);
dynamic array = result.jobs;
foreach (var item in array)
{
MessageBox.Show("{0}{1}", item.timeleft, item.mbleft);
}

Categories

Resources