0

I'm relatively new to dealing with JSON. But have successfully created a few classes that return exactly what I want. However, this response is baffling me.

I have reviewed and attempted the various examples on the site to convert my JSON response into a class. However, I continue to get run-time errors. Any pointers on where I'm going wrong would be appreciated.

JSON Response

{
    "locationResponse": {
        "locations": [
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:Jonathon Doe,state:WA,houseNum:23619",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:Jon Doe,state:WA,houseNum:23619",
            "ad1c:2dbf:fadf:2e87",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:John Doe,state:WA,houseNum:23619",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:JJ Doe,state:WA,houseNum:23619"
        ]
    }
}

Class Definition

[Serializable]
public class locationResponseResponse
{
    public locationResponse locationResponse { get; set; }
}
[Serializable]
public class locationResponse
{
    public location[] locations { get; set; }
}
[Serializable]
public class location
{
    public string E911AID { get; set; }
    public string streetDir { get; set; }
    public string street { get; set; }
    public string zip { get; set; }
    public string city { get; set; }
    public string streetNameSuffix { get; set; }
    public string name { get; set; }
    public string state { get; set; }
    public string houseNumber { get; set; }
}

Deserialize Snippet

public locationResponseResponse GetlocationResponseResponse(string jsonString)
{
    locationResponseResponse _response = new locationResponseResponse();
    if (!string.IsNullOrEmpty(jsonString))
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        _response = ser.Deserialize<locationResponseResponse>(jsonString);
    }
    return _response;
}

Run-time Error Received

No parameterless constructor defined for type of BlackFlagAPI.locationResponse[].

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Consider using Newtsoft.Json. It's the most popular json serializer. – CodesInChaos Feb 21 '15 at 09:11
  • 1
    The `location`s in the json example are strings, not json objects. So a json deserializer can't turn them into your `location` class. You'll need to register a custom parser for that. – CodesInChaos Feb 21 '15 at 09:15
  • Next time you post json, please use pretty printed json. Makes it much easier to see what's going on. – CodesInChaos Feb 21 '15 at 09:25
  • 2
    I fixed your JSON, this one works fine: https://gist.github.com/cubrr/ac9b70961301193caf49 – cbr Feb 21 '15 at 09:37

3 Answers3

2

The locations in the json example are strings, not json objects. So a json deserializer can't turn them into your location class. The string content isn't a serialized json document either.

You'll need to register a custom parser for that, but since I never worked with JavascriptSerializer, I can't tell you how.

Alternatively, if you have control over the source of the json, encode the location data using json instead of embedding a custom format in a string.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
0

For the JSON that you have posted, the class would be similar to below:

public class LocationResponse
{
    public List<string> locations { get; set; }
}

public class Root
{
     public LocationResponse locationResponse { get; set; }
}

You would need to then manually parse the locations. Else, you need to correct the JSON structure.

Ankit Vijay
  • 3,752
  • 4
  • 30
  • 53
0

Locations in your json is not json objects. They are strings in the form name:value separated by ,.

So you need to parse it in two steps

1- Deserialize the json

var root = new JavaScriptSerializer().Deserialize<RootObject>(json);

2- Parse each string

var addrs = root.locationResponse.locations
                .Select(x => x.Split(','))
                .Select(parts =>
                {
                    var l = new Location();
                    var props = l.GetType().GetProperties();
                    foreach (var part in parts)
                    {
                        var kv = part.Split(new char[] { ':' }, 2);
                        var prop = l.GetType().GetProperty(kv[0]);
                        if(prop != null)
                            prop.SetValue(l, kv[1]);

                    }
                    return l;
                })
                .ToList();

public class Location
{
    public string E911AID { get; set; }
    public string streetDir { get; set; }
    public string street { get; set; }
    public string zip { get; set; }
    public string city { get; set; }
    public string streetNameSuffix { get; set; }
    public string name { get; set; }
    public string state { get; set; }
    public string houseNum { get; set; }
}

public class LocationResponse
{
    public List<string> locations { get; set; }
}

public class RootObject
{
    public LocationResponse locationResponse { get; set; }
}
EZI
  • 15,209
  • 2
  • 27
  • 33
  • Thank you, upon more digging it appears the service I'm getting the JSON response has a bug. I hadn't noticed the near-empty row containing only an ID. This seems to be the crux of the issue. Once I dropped this bad line, even my original code worked. Now I need to determine if JSON output is flawed, and potentially fix inline or simply error out. Really appreciate all the assistance. – Allan Lockridge Feb 21 '15 at 21:18