Change existing JSON message format into new with fields in C#? - 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?

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

C# repeating the same field name in class to allow serializing to JSON

I am trying to build a class which I serialize to become the body of a web request.
The output I'm trying to achieve when serializing the object is :
{
"findCompletedItemsRequest": {
"keywords": "searchtext",
"itemFilter": [
{
"name": "SoldItemsOnly",
"value": "true"
}
],
"outputSelector": "PictureURLLarge",
"outputSelector": "SellerInfo",
"paginationInput": {
"entriesPerPage": "100",
"pageNumber": "1"
}
}
}
For the field 'outputSelector', I can have it in there 0, 1 or many times.
How would I define this in my class ? I have tried searching but I'm unsure what I'm trying to achieve may be called. If I use a list or array it just creates outputSelect JSON property that has an array in it, not multiple outputSelector properties.
Here is what I have so far (other critique welcomed as I'm from a procedural programming background)
public class eBaySearchBody
{
public FindCompletedItemsRequest findCompletedItemsRequest = new FindCompletedItemsRequest();
public class FindCompletedItemsRequest
{
public string keywords { get; set; }
public List<itemFilters> itemFilter { get; set; }
public string sortOrder { get; set; }
public PaginationInput paginationInput = new PaginationInput();
}
public class PaginationInput
{
public string entriesPerPage { get; set; }
public string pageNumber { get; set; }
}
public class itemFilters
{
public string name { get; set; }
public string value { get; set; }
}
}
It's not a valid JSON. It has SyntaxError: Duplicate key 'outputSelector' on line 9.
If you consider using an array of outputSelector, the code needs to be modified as below to produce valid JSON.
Sample Valid JSON:
{
"findCompletedItemsRequest": {
"keywords": "searchtext",
"itemFilter": [{
"name": "SoldItemsOnly",
"value": "true"
}],
"outputSelector": ["PictureURLLarge", "SellerInfo"],
"paginationInput": {
"entriesPerPage": "100",
"pageNumber": "1"
}
}
}
Sample C# Code Modification:
namespace Solutions{
using System.Collections.Generic;
using Newtonsoft.Json;
public class EBaySearchBody{
public class FindCompletedItemsRequest{
[JsonProperty("keywords", Order = 1)]
public string Keywords { get; set; }
[JsonProperty("itemFilter",Order = 2)]
public List<ItemFilter> ItemFilters { get; set; }
[JsonProperty("outputSelector", Order = 3)]
public List<string> OutputSelectors { get; set; }
[JsonProperty("paginationInput", Order = 4)]
public PaginationInput PaginationInput { get; set; }
}
public class PaginationInput{
[JsonProperty("entriesPerPage", Order = 1)]
public string EntriesPerPage { get; set; }
[JsonProperty("pageNumber", Order = 2)]
public string PageNumber { get; set; }
}
public class ItemFilter{
[JsonProperty("name", Order = 1)]
public string Name { get; set; }
[JsonProperty("value", Order = 2)]
public string Value { get; set; }
}
[JsonProperty("findCompletedItemsRequest")]
public FindCompletedItemsRequest FindCompletedItemsRequestObject { get; set; }
/// <summary>
/// Create a <see cref="EBaySearchBody"/>object and serialize it to a JSON stream
/// </summary>
/// <returns></returns>
public static string WriteFromObject()
{
//Create EbaySearchBody object.
EBaySearchBody searchBody = new EBaySearchBody(){
FindCompletedItemsRequestObject = new FindCompletedItemsRequest(){
Keywords = "searchtext",
ItemFilters = new List<ItemFilter>(){
new ItemFilter {
Name = "SoldItemsOnly",
Value = "true"
}
},
OutputSelectors = new List<string>(){
"PictureURLLarge",
"SellerInfo"
},
PaginationInput = new PaginationInput(){
EntriesPerPage = "100",
PageNumber = "1"
}
}
};
return JsonConvert.SerializeObject(searchBody);
}
}
}

C# Parse nested JSON Array to get values

I've been searching and trying to get this to work for hours and i'm completely out of ideas. I have JSON text that i'm trying to read and can't see it get it to work. Here is the JSON text.
[ {
"first_aired": "2018-03-03T01:00:00.000Z",
"episode": {
"season": 3,
"number": 13,
"title": "Warning Shot",
"ids": {
"trakt": 2814272,
"tvdb": 6445735,
"imdb": "tt7462514",
"tmdb": 1429184,
"tvrage": 0
}
},
"show": {
"title": "Blindspot",
"year": 2015,
"ids": {
"trakt": 98980,
"slug": "blindspot",
"tvdb": 295647,
"imdb": "tt4474344",
"tmdb": 62710,
"tvrage": 44628
}
} }, {
"first_aired": "2018-03-03T01:00:00.000Z",
"episode": {
"season": 2,
"number": 16,
"title": "Hammock + Balcony",
"ids": {
"trakt": 2874663,
"tvdb": 6535389,
"imdb": "tt7820776",
"tmdb": 1428050,
"tvrage": 0
}
},
"show": {
"title": "MacGyver",
"year": 2016,
"ids": {
"trakt": 107792,
"slug": "macgyver-2016",
"tvdb": 311902,
"imdb": "tt1399045",
"tmdb": 67133,
"tvrage": {}
}
} } ]
I'm trying to get the "episode -> season" and "episode - > number"
This is the code ive been working with and also a fiddle below.
string json = "[{\"first_aired\":\"2018-03-03T01:00:00.000Z\",\"episode\":{\"season\":3,\"number\":13,\"title\":\"Warning Shot\",\"ids\":{\"trakt\":2814272,\"tvdb\":6445735,\"imdb\":\"tt7462514\",\"tmdb\":1429184,\"tvrage\":0}},\"show\":{\"title\":\"Blindspot\",\"year\":2015,\"ids\":{\"trakt\":98980,\"slug\":\"blindspot\",\"tvdb\":295647,\"imdb\":\"tt4474344\",\"tmdb\":62710,\"tvrage\":44628}}},{\"first_aired\":\"2018-03-03T01:00:00.000Z\",\"episode\":{\"season\":2,\"number\":16,\"title\":\"Hammock + Balcony\",\"ids\":{\"trakt\":2874663,\"tvdb\":6535389,\"imdb\":\"tt7820776\",\"tmdb\":1428050,\"tvrage\":0}},\"show\":{\"title\":\"MacGyver\",\"year\":2016,\"ids\":{\"trakt\":107792,\"slug\":\"macgyver-2016\",\"tvdb\":311902,\"imdb\":\"tt1399045\",\"tmdb\":67133,\"tvrage\":null}}}]";
JArray obj = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(json);
foreach (var result in obj)
{
foreach (JObject tvshow in result["episode"])
{
string season_num = (string)tvshow["season"];
string episode_num = (string)tvshow["number"];
Console.WriteLine(season_num + " - " + episode_num );
}
}
https://dotnetfiddle.net/speUyL
Thank's for any help anyone can give me!
You actually have nested objects, so you will need to first extract the episode object and then from the episode you can access it's properties which are number and season etc:
foreach (var result in obj)
{
var episode = result["episode"];
Console.WriteLine(episode["season"]);
Console.WriteLine(episode["number"]);
}
This prints the result you are trying to do. Following is the updated fiddle demo:
https://dotnetfiddle.net/WN545C
A easy approach is to have DTO c# classes for your json and then Deserialize the json result in to List<T>. The classes for your json would be :
public class Ids
{
public int trakt { get; set; }
public int tvdb { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public int tvrage { get; set; }
}
public class Episode
{
public int season { get; set; }
public int number { get; set; }
public string title { get; set; }
public Ids ids { get; set; }
}
public class Ids2
{
public int trakt { get; set; }
public string slug { get; set; }
public int tvdb { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public object tvrage { get; set; }
}
public class Show
{
public string title { get; set; }
public int year { get; set; }
public Ids2 ids { get; set; }
}
public class Season
{
public DateTime first_aired { get; set; }
public Episode episode { get; set; }
public Show show { get; set; }
}
An easy way to get the classes generated is by using Json2CSharp.com or either using the Visual Studio feature which can paste JSON as C# classes using Paste Special.
and now you can deserialize and access each season data more better way:
var seasons = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Season>>(json);
foreach (var season in seasons)
{
Console.WriteLine(season.episode.title);
Console.WriteLine(season.first_aired);
Console.WriteLine(season.episode.season);
Console.WriteLine(season.episode.number);
}
You can play with the demo for that here:
https://dotnetfiddle.net/hukLQI

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