1

I'm trying to understand the best way to set up a class in .NET 3.5. I have a JSON object that's a collection of Order Shipments defined as something like this:

[
    {
        "BaseOrder": {
            "order_id": "503",
            "BillingAddress": {
                "bill_address_id": "984",
                "order_id": "503"
            },              
            "Lookup": [
                {
                    "lookup_id": "4070",
                    "order_id": "503"   
                },
                {
                    "lookup_id": "4071",
                    "order_id": "503"   
                }
            ],              
            "ShippingAddress": {
                "ship_address_id": "983",
                "order_id": "503"
            }
        },
        "BaseOrderShipment": {
            "shipment_id": "535",
            "order_id": "503"           
        },
        "BaseOrderShipmentLineitem": [
            {
                "line_item_id": "820",          
                "order_id": "503",
                "shipment_id": "535"
            },
            {
                "line_item_id": "821",          
                "order_id": "503",
                "shipment_id": "535"
            }
        ]
    },
    {
        "BaseOrder": {
            "order_id": "5030",
            "BillingAddress": {
                "bill_address_id": "9840",
                "order_id": "5030"
            },              
            "Lookup": [
                {
                    "lookup_id": "40700",
                    "order_id": "5030"
                },
                {
                    "lookup_id": "40710",   
                    "order_id": "5030"  
                }
            ],  
            "ShippingAddress": {
                "ship_address_id": "9830",
                "order_id": "5030"
            }
        },
        "BaseOrderShipment": {
            "shipment_id": "5350",
            "order_id": "5030"          
        },
        "BaseOrderShipmentLineitem": [
            {
                "line_item_id": "8200",         
                "order_id": "5030",
                "shipment_id": "5350"
            }
        ]
    }
]

I'm not quite sure how I should set the class up. I'm planning on putting the class in it's own file and referencing it from my program.

This is what I'm planning on putting in the class file:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace MyCompany.MyProgram
{

public class RootObject
{
    [JsonProperty("BaseOrder")]
    public BaseOrder BaseOrder { get; set; }

    [JsonProperty("BaseOrderShipment")]
    public BaseOrderShipment BaseOrderShipment { get; set; }

    [JsonProperty("BaseOrderShipmentLineitem")]
    public IList<BaseOrderShipmentLineitem> BaseOrderShipmentLineitem { get; set; }
}

public class BaseOrders
{
    [JsonProperty("order_id")]
    public int OrderId { get; set; }

    [JsonProperty("ShippingAddress")]
    public ShippingAddress ShippingAddress { get; set; }

    [JsonProperty("BillingAddress")]
    public BillingAddress BillingAddress { get; set; }

    [JsonProperty("Lookup")]
    public IList<Lookup> Lookup { get; set; }
}

public class BaseOrderShipment
{
    [JsonProperty("shipment_id")]
    public int ShipmentId { get; set; }

    [JsonProperty("order_id")]
    public int OrderId { get; set; }
}

public class BillingAddress
{
    [JsonProperty("bill_address_id")]
    public int BillAddressId { get; set; }

    [JsonProperty("order_id")]
    public int OrderId { get; set; }
}

public class ShippingAddress
{
    [JsonProperty("ship_address_id")]
    public int ShipAddressId { get; set; }

    [JsonProperty("order_id")]
    public int OrderId { get; set; }
}

public class Lookup
{
    [JsonProperty("lookup_id")]
    public int LookupId { get; set; }

    [JsonProperty("order_id")]
    public int OrderId { get; set; }
}

public class BaseOrderShipmentLineitem
{
    [JsonProperty("line_item_id")]
    public int LineItemId { get; set; }

    [JsonProperty("order_id")]
    public int OrderId { get; set; }

    [JsonProperty("shipment_id")]
    public int ShipmentId { get; set; }
}

I'm creating an instance of the class using:

string fileName = @"C:\path\to\myFile.json";
var obj = ParseOrderShipments(fileName);
public static List<RootObject> ParseOrderShipments(string fileName)
{
    //RootObject retObj = new RootObject();
    List<RootObject> retObj = JsonConvert.DeserializeObject<List<RootObject>>(File.ReadAllText(fileName));
    return retObj;
}

Is this a good approach to this, or is there a better way to do it?

6
  • What JSON serialization engine are you using? You probably won't need most of the JsonProperty attributes, since the property names match the JSON element names Commented Apr 20, 2015 at 6:23
  • 3
    @jared: see this link to generate C# classess from JSON. json2csharp.com/# Commented Apr 20, 2015 at 6:50
  • 3
    @Konamiman in my experience, you should not rely on the property names. Make the binding explicit and you don't have to worry about refactors spoiling your day. Commented Apr 20, 2015 at 7:02
  • @Gusdor true but if you use those only as DTOs you should realize that changing them can cause problems - anywhere you will surely have a test-suite to notify you of the fact ;) - the rest is YAGNI/KISS IMO Commented Apr 20, 2015 at 7:27
  • @Konamiman die engine seems to be JSON.net (based on the imports) Commented Apr 20, 2015 at 7:28

2 Answers 2

1

IMHO that is a good translation of the JSON to C#, but your problem here is the JSON structure itself: it looks like it has a lot of redundant fields (e.g. the order_id is repeated a lot), and in general it seems it was pulled straight out of a database, i.e. it's using a relational model, with plenty of IDs that reference other "tables", rather than an object-oriented model.

There's a famous quote saying "All problems in computer science can be solved by another level of indirection"; depending on what you want to do with this data, you might want to build another set of classes that represent orders in a more object-oriented fashion, e.g. line items being properties of shipments.

Sign up to request clarification or add additional context in comments.

Comments

1

Why not just use some generator like http://json2csharp.com/

Here is what its output is:

public class BillingAddress
{
    public string bill_address_id { get; set; }
    public string order_id { get; set; }
}

public class Lookup
{
    public string lookup_id { get; set; }
    public string order_id { get; set; }
}

public class ShippingAddress
{
    public string ship_address_id { get; set; }
    public string order_id { get; set; }
}

public class BaseOrder
{
    public string order_id { get; set; }
    public BillingAddress BillingAddress { get; set; }
    public List<Lookup> Lookup { get; set; }
    public ShippingAddress ShippingAddress { get; set; }
}

public class BaseOrderShipment
{
    public string shipment_id { get; set; }
    public string order_id { get; set; }
}

public class BaseOrderShipmentLineitem
{
    public string line_item_id { get; set; }
    public string order_id { get; set; }
    public string shipment_id { get; set; }
}

public class RootObject
{
    public BaseOrder BaseOrder { get; set; }
    public BaseOrderShipment BaseOrderShipment { get; set; }
    public List<BaseOrderShipmentLineitem> BaseOrderShipmentLineitem { get; set; }
}

You can later deserialize the string using JsonConvert.DeserializeObject<List<RootObject>>(jsonString);

3 Comments

These classes are far worse than the OP's proposal; they don't respect C# naming conventions, they'll break if names are refactored, and they use strings when ints are enough.
This is just a proposition that saves you a lot of typing. You can always add the attributes later on. And how did you guess by looking at the json what is int and what is a string order_id may well be defined as string in the database. What if you have to verify that json against some business logic. For example you're writing an web api and someone has posted you that json and the order_id is missing or something else. How would you generate the error response saying that a order_id must be a valid integer number but they have supplied "order1" as the value? It depends on what the dev wants.
Also mapping json string directly to business entities is not a good idea thus the naming convention is justified to be broken here. I personally prefer my POCO (data) object to map directly to whatever they "come" from (database, json, xml)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.