如何保留这种 json 格式,同时在序列化之前添加它?

Posted

技术标签:

【中文标题】如何保留这种 json 格式,同时在序列化之前添加它?【英文标题】:how can I preserve this json format, while adding to it before serializing it? 【发布时间】:2021-12-30 10:58:00 【问题描述】:

我有一个相当复杂的 json 文件,我正在反序列化为要显示到 datgridview 的数据表。

json 文件中包含很多值和属性。

我自己添加了大约 5-6 个属性,以便在我的软件中进行操作。当我在这里完成我的软件时,我想将此数据表序列化回 json。但添加了属性。

问题是我终于想出了如何将我的属性序列化回文件,并意识到在此过程中我似乎没有将所有其他字段序列化回文件中。它们有几十个,它们是嵌套的。我不确定如何将所有嵌套信息放入数据表中。

谁能解释或帮助我将所有这些信息打包到我的数据表中? 下面将是一些代码片段来展示我到目前为止的过程。

这是重头戏

这是我反序列化文件并加载到 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();

    

这是触发序列化回文件的简单按钮单击事件

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

最后是json文件的sn-p,这只是数百个列表中的一项


"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"
    
]
 

编辑

如果我单击 m 按钮,我应该添加我现在的结果

    [
    
    "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
    
    ]

还要注意我的课程是在线使用 quicktype.io,所以课程可以处理整个文件没有问题(我会假设)

再次编辑

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 ;

最新编辑 以下代码将考虑然后将对象设置为 DGV。除了这一小段代码,我不需要加载其他内容。

var v = JsonConvert.DeserializeObject<ToolJson> 
(File.ReadAllText(@"testLibrary.json"));

        //set DGV source to our datums 
        toolDataGridView.DataSource = v.Datums.Cast<IInteresting> 
        ().ToList();

最新编辑

 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;
    

 

编辑包括序列化 下面的按钮单击事件应该模拟用户关闭表单时应该发生的情况。按钮单击而不是进行测试。 发生的情况是它序列化,但格式不正确。

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

【问题讨论】:

这样的? Bmc bmc = 基准.Bmc;双重成本=基准。成本;字符串员工 = datum.employee;字符串等级 = datum.Grade;字符串位置 = datum.location;字符串描述=数据。描述;几何几何 = datum.Geometry; //几何的子类 bool csp = datum.Geometry.Csp;双直径 = datum.Geometry.Dc; bool hand = datum.Geometry.Hand;等等..? 在我的 foreach 循环中几乎将每个属性分配给一个变量并将它们全部放入数据表中?然后只显示我需要的? 你的实际课程是否可以发布到问题中? 是的,现在就添加 将 json 文件添加到我的问题的最后 【参考方案1】:

在某个地方添加这个,在另一个类中:

    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;
        
    

这只是一个片段;您可以稍后填写其他道具。我已经演示了一个具有 3 个道具的界面。一个是 Datum 的直接属性(描述)。另外两个是挖掘嵌套数据的道具;他们需要实现,就像我展示的那样,包括JsonIgnore 标签。您剩余的道具可能类似于第一种情况(已经是 Datum 的道具,只需要在界面中提及)或嵌套数据(需要在界面中发明一个新名称和一个新代码将其从层次结构中挖掘出来)

然后将这段代码放在一个名为 Form1 的新表单中,其中包含一个 DataGridView1 和一个 Button1(在设计器中):

    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

datagridview 获取IInteresting 的列表,它只为IInteresting 上的道具创建列,所以在这种情况下,我看到 3 列(3 个道具):

编辑一些数据

点击按钮。网格的数据源(它包含所有数据,而不仅仅是可见数据)被序列化,输出包含所有数据


添加新数据,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; 

【讨论】:

有趣,我从未尝试过使用界面。只阅读它们。我会试一试。我的软件现在乱七八糟,所以希望我能在这一切之后把它修补起来! 构成界面的第一位给了我 9 个错误。找不到几何的定义。当我做另一部分时,我会继续看看它是否会自行修复 可能是因为您放置接口的“某处”不在 QuickType 命名空间内,文件顶部也没有using QuickType 我忘了说“如果你有新的属性想要添加到 json 输出,那么你应该 a) 把它们放在接口中,b) 把它们放在基准(如果它们类似于描述)或子级别对象并为它们放置***属性(如果它们类似于 Geometry.Dc)和 c)不要将 JsonIgnore 放在它们上,因为您确实想要序列化它们(但 DO JsonIgnore 任何 GeometryDc 风格的***“挖掘机”属性) 是的。我注意力不集中,我买了一本关于 C# 的书,我在闲暇时间读过,但如果我的 4 个孩子不打扰我,我仍然会在它开始谈论 OOP 时碰壁哈哈。无论如何...非常感谢你!非常感谢您在此处对我的帖子的持续投入!

以上是关于如何保留这种 json 格式,同时在序列化之前添加它?的主要内容,如果未能解决你的问题,请参考以下文章

Marshall @Id 到 JSON,同时保留 Java 8 时间格式

android 怎么添加gson

将类序列化为 .json 文件

如何在 R 数据框中取消嵌套列表,同时保留键和值?

如何在发送 Nestjs 之前格式化响应?

Json & pickle 数据序列化