2

I have a JSON file that I need to convert to a C# object, which will then be written to a SQL database. The JSON is in this format:

{
    "AK": {
        "Anchorage": [{
            "Name": "John Doe",
            "Address": "123 Main St.",
            "City": "Anchorage",
            "State": "AK",
            "Zip": "12345"
        }],
        "Fairbanks": [{
            "Name": "Sally Smith",
            "Address": "987 Main St.",
            "City": "Fairbanks",
            "State": "AK",
            "Zip": "98765"
        }]
    }
}

I have a C# class that looks like this:

public class Location
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Zip { get; set; }
}

public class Locations
{
    public List<Location> Location { get; set; }
}

I'm using the Newtonsoft JSON library. I'm not sure how I can grab the inner values (Name, Address, City, State, Zip) when the outer values "AK", "Anchorage", "Fairbanks" do not have common names?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
PixelPaul
  • 2,609
  • 4
  • 39
  • 70
  • Pretty sure I've answered the question properly now, including the iterations. Please re-check my answer! – Nick Bull Aug 01 '16 at 13:42
  • So, basically, you got your root "AK", containing two items "Anchorage" and "Fairbanks", each of those being an array of locations containing only one item? Once you grasp the structure, that doesn't seem too hard. – Nyerguds Aug 01 '16 at 14:08
  • @Nyerguds it's actually not so easy at first to understand how to iterate through JSON if you're not familar with doing so. The difference between `{}` and `[]` can be tricky to explain, especially if the structure is like `[ { [ ] } ]` vs `[ [ { } ] ]`, for iteration when you're familar with strongly-typed objects. – Nick Bull Aug 01 '16 at 14:12
  • Of course, if it's not just "Anchorage" and "Fairbanks", and instead there can be _more_ locations like that... then it gets tricky, and you might have to go with defining "AK" as a `Dictionary` for this structure... somehow. I'm not familiar with NewtonSoft, but with `System.Runtime.Serialization.Json` I know Dictionaries are a real pain. – Nyerguds Aug 01 '16 at 14:20
  • Seems the real problem here is indeed that the json data offers things that are actually repeating data as if they're hard properties instead. Bad form, especially on root elements. Doubly so since it's redundant data, since all the internal entries contain the state and city again. – Nyerguds Aug 01 '16 at 14:29
  • Possible duplicate of [How can I parse JSON with C#?](https://stackoverflow.com/questions/6620165/how-can-i-parse-json-with-c) – StayOnTarget Sep 19 '18 at 12:57

5 Answers5

2

Using NewtonSoft:

Location location = JsonConvert.DeserializeObject<Location>(json);

Where your classes look like this:

public class Location
{
    public IList<Address> Addresses { get; set; }
}

public class Address {
    public string AddressName { get; set; }
    [JsonProperty("Name")] # You'll need attributes if the dataset has another name than that of the object's property.
    public string PersonName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

Example modified from here.

Quick update, I re-read the question and saw you're having difficulty iterating over the object too. Missed that first time round, here you go:

var locations = new List<Location>();
dynamic deserialisedJson = JsonConvert.DeserializeObject(json);

// E.g., json => List ( "AK": { ... }, ... )
// so we're iterating the items of that "list", e.g., "AK": { ... }, etc.
foreach (var state in deserialisedJson)
{
    // e.g., "AK": { ... } => List ( Anchorage: [{ ... }], Fairbanks: [{ ... }] )
    // so we're iterating the items of each item, e.g., Anchorage: [{ ... }], etc.
    foreach (var addresses in state)
    {
        // e.g., Anchorage: [{ ... }, { ... }] => List ( { ... }, { ... } )
        // because Anchorage, etc., are arrays, we have to iterate their contents too, to get each address object within them (represented as { ... } above:
        foreach (var address in addresses) {
            Location location = JsonConvert.DeserializeObject<Location>(address);
            // do stuff with location, e.g.,
            locations.Add(location);
        }
    }
}
Nick Bull
  • 9,518
  • 6
  • 36
  • 58
0

did you try json2csharp.com

  • -Go to json2csharp.com

  • Past your JSON in the Box.

  • Clik on Generate.

  • You will get C# Code for your object model

  • Deserialize by var model = JsonConvert.DeserializeObject(json); using NewtonJson

Jimmy Jain
  • 17
  • 4
0

Please take a look at this question:

Json.net use the JsonProperty to get the inherited property

Writing a converter, that inherits from JsonConverter:

public class LocationConverter: JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Location));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Location location = jo.ToObject<Location>();
        Location.etc = jo.SelectToken("etc.etc").ToObject<type>();
        .
        .
        .
        return location;

    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

With this you can load properties that are not introduced in the same way in the class as in the json file

You can use it like:

Location location = JsonConvert.DeserializeObject<Location>(json, new LocationConverter());
Community
  • 1
  • 1
Attila Horváth
  • 562
  • 1
  • 5
  • 16
0

you can serialize and deserialize and bind to classobject

var JsonResult = JsonConvert.SerializeObject(Account);

var obj = JsonConvert.DeserializeObject(JsonResult);

GirishBabuC
  • 1,267
  • 15
  • 20
-1

"Anchorage", "Fairbanks", etc. should not be a "property name" but rather be inside the object itself like

{
"AK": 
    [{
        "AddressName": "Anchorage",
        "Name": "John Doe",
        "Address": "123 Main St.",
        "City": "Anchorage",
        "State": "AK",
        "Zip": "12345"
    }, {
        "AddressName": "Fairbanks",
        "Name": "Sally Smith",
        "Address": "987 Main St.",
        "City": "Fairbanks",
        "State": "AK",
        "Zip": "98765"
    }]
}

point at which you can simply iterate over the JSON like you normally would.

iuliu.net
  • 6,666
  • 6
  • 46
  • 69
  • 2
    I agree, but that is the format of the file that is being received. I need to make this work with what I am provided. – PixelPaul Aug 01 '16 at 13:05