skip to Main Content

In C# I want to created JSON String or Object with the format below:

{
    "retailer_br_id" : "5473182",
    "retailer_external_id": "",
    "erp_invoice_number" : "INV-202302",
    "invoice_date": "2023-04-06T17:00:00.000Z",
    "status" : 1,
    "details":[{
        "sku_external_id": "TD5015151432201",
        "quantity" : "2",
        "price_per_item": "14.5"
        },
        {
            "sku_external_id": "000005020170898446",
            "quantity" : 1,
            "price_per_item": 10.50
        }
    ]
}

I tried the following, but it seems not working, it only gives me the dList value…………………………………………………………………………………………………………………..

DataTable dt = new DataTable("Details");
dt.Columns.Add("sku_external_id", typeof(string));

//Data  
dt.Rows.Add("0000000000");
dt.Rows.Add("111111111");
dt.Rows.Add("1222222222");
dt.Rows.Add("3333333333");

Root rt = new Root();
rt.retailer_br_id = "32423432432424";
rt.retailer_external_id = "";
rt.erp_invoice_number = "PBY-202304";
DateTime d = DateTime.Now;
string dateString = d.ToString("Y-m-d H:i:s");
rt.invoice_date = dateString;

List<Detail> dList = new List<Detail>();

for (int i = 0; i < dt.Rows.Count; i++)
{
    Detail det = new Detail();
    
    det.sku_external_id = (string)dt.Rows[i]["sku_external_id"];
    
    dList.Add(det);
}

string json = JsonConvert.SerializeObject(dList, Formatting.Indented);
textBox1.Text = json;

3

Answers


    1. You are serializing dList, but not root, this is why it show the serialized dList.

    2. Missing assign the dList to rt.details.

    rt.details = dList;
            
    string json = JsonConvert.SerializeObject(rt, Formatting.Indented);
    
    1. To serialize date to ISO 8601 format:
    string dateString = d.ToString("yyyy-MM-ddTHH:MM:sss.fffZ");
    

    Alternatives

    1. Instead of using foreach loop to iterate and add items into dList, you may achieve with:
    dList = JArray.FromObject(dt)
        .ToObject<List<Detail>>();
    
    1. Name the properties as Pascal Case, and use JsonProperty attribute to define the property name used in serialization and deserialization.
    public class Detail 
    { 
        [JsonProperty("sku_external_id")] 
        public string SkuExternalId { get; set; }
    
        [JsonProperty("quantity")]
        public object Quantity { get; set; }
    
        [JsonProperty("price_per_item")]
        public object PricePerItem { get; set; }
    }
    
    public class Root
    {
        [JsonProperty("retailer_br_id")]
        public string RetailerBrId { get; set; }
    
        [JsonProperty("retailer_external_id")]
        public string RetailerExternalId { get; set; }
    
        [JsonProperty("erp_invoice_number")]
        public string ErpInvoiceNumber { get; set; }
    
        [JsonProperty("invoice_date")]
        public DateTime InvoiceDate { get; set; }
    
        [JsonProperty("status")]
        public int Status { get; set; }
    
        [JsonProperty("details")]
        public List<Detail> Details { get; set; }
    }
    
    1. Change invoice_date property to DateTime type so it will serialize and display the format in ISO 8601, instead of defining the format manually.
    rt.invoice_date = DateTime.Now;
    
    [JsonProperty("invoice_date")]
    public DateTime invoice_date { get; set; }
    
    Login or Signup to reply.
  1. The json will only have the value of dList, because you have not assigned rt to the det object. I am assuming that det has a property which can be assigned to with the value of rt e.g.

    for (int i = 0; i < dt.Rows.Count; i++)
    {
        Detail det = new Detail();
                    
        det.sku_external_id = (string)dt.Rows[i]["sku_external_id"];
        det.root = rt;
        
        dList.Add(det);
    }
    

    if det does not have a property of type root, you will need to add one.

    It may be that you do not want root to be assigned to each instance of det to the list. If you want to assign it once outside the list then you would need a wrapper object eg.

    class MyObject {
       public  Root root{ get; set; }
       public  List<Detail> dList { get; set; }
    }
    

    The modified code will then look like…

    MyObject myobject = new MyObject();
    List<Detail> dList = new List<Detail>();
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        Detail det = new Detail();
    
        det.sku_external_id = (string)dt.Rows[i]["sku_external_id"];
    
        dList.Add(det);
    }
    myobject.root = myobject;
    myobject.dlist = dList;
    
    string json = JsonConvert.SerializeObject(myobject, Formatting.Indented);
    textBox1.Text = json;
    
    Login or Signup to reply.
  2. you can just use an anonymous type

    var obj = new
        {
            retailer_br_id = 5473182,
            retailer_external_id = 0,
            erp_invoice_number = "INV-202302",
            invoice_date = "2023-04-06T17=00=00.000Z",
            status = 1,
            details = new[] { 
            new {
            sku_external_id= "TD5015151432201",
            quantity = 2,
            price_per_item= 14.5
            },
            new {
                sku_external_id= "000005020170898446",
                quantity = 1,
                price_per_item= 10.50
            }
          }
        };
    
    string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
    

    now if you want, you can convert this JSON to a C# classes online
    using this link for example https://json2csharp.com/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search