raklos
raklos

Reputation: 28555

help with parsing json in .net

I need help parsing this json, in this snippet there are only three items, but the list goes up to around 2000.

 {"1":
        {"Latitude":52.1643540,
         "Longitude":-2.154353,
         "Name":"AAA"
         },
     "2":
        {"Latitude":53.13,
         "Longitude":-2.13445,
         "Name":"BBB"
        },
     "3":
        {"Latitude":55.143243,
         "Longitude":-2.45234,
         "Name":"CCC"
        }}

I want to produce a List of "Place" objects and I want the number to be used as an ID eg a class Place with properties PlaceId Latitude, Longitude, Name.

giving for the first list element:

place.PlaceId = 1
place.Latitude = 52.1643540
place.Longitude = 2.154353
place.Name = "AAA"

Upvotes: 3

Views: 848

Answers (6)

Zack
Zack

Reputation: 608

Hi if you can't change your JSON you could deserialize it by doing the following:

    var serializer = new JavaScriptSerializer();
    var deserializedDictionary = serializer.Deserialize<Dictionary<string, PlaceDetails>>(jsonString);

    var result = new List<Place>();

    foreach (var key  in deserializedDictionary.Keys)
    {
        result.Add(new Place(key, deserializedDictionary[key]));
    }

Classes Required:

    public class PlaceDetails
    {
        public float Latitude { get; set; }
        public float Longitude { get; set; }
        public string Name { get; set; }
    }

    public class Place
    {
        public Place(string placeID, PlaceDetails placeDetails)
        {
            this.PlaceID = Convert.ToInt32(placeID);
            this.Latitude = placeDetails.Latitude;
            this.Longitude = placeDetails.Longitude;
            this.Name = placeDetails.Name;
        }

        public int PlaceID { get; set; }
        public float Latitude { get; set; }
        public float Longitude { get; set; }
        public string Name { get; set; }
    }

you'll still need a reference to System.Web.Extensions.dll and using the System.Web.Script.Serialization namespace.

Hope this helps.

Upvotes: 1

Joe Simmonds
Joe Simmonds

Reputation: 545

If you are able to change that JSON then I would go with James' answer but if it turns out tat you can't things will get more complicated. I wasn't able to find a JSON serialiser that would understand that format with the index numbers in the JSON as property names. It does however appear to be valid and is well understood by all of the browsers I tried.

I think your best option here is to use a Javascript library for .net (there are a couple of these but I like IronJS). Using this you can just execute the JSON and read out the result. Here is some sample code that reads your JSON from a file and writes the results to the console.

public class Place
{
    public int ID { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public string Name { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        var ctx = new IronJS.Hosting.CSharp.Context();
        string json;
        using (TextReader reader = File.OpenText("array_items.txt"))
        {
            json = reader.ReadToEnd();
        }

        CommonObject result= (CommonObject)ctx.Execute("var x=" + json);
        Dictionary<uint,BoxedValue> indexes = new Dictionary<uint,BoxedValue>();
        result.GetAllIndexProperties(indexes, uint.MaxValue);
        List<Place> places = new List<Place>();

        foreach (uint idx in indexes.Keys)
        {
            Place p = new Place();
            p.ID = (int)idx;
            p.Name = (string)indexes[idx].Object.Members["Name"];
            p.Latitude = (double)indexes[idx].Object.Members["Latitude"];
            p.Longitude = (double)indexes[idx].Object.Members["Longitude"];
            places.Add(p);
        }

        foreach (Place place in places)
        {
            Console.WriteLine("ID = {0}", place.ID);
            Console.WriteLine("Name = {0}", place.Name);
            Console.WriteLine("Latitude = {0}", place.Latitude);
            Console.WriteLine("Longitude = {0}", place.Longitude);
        }

        Console.ReadKey();
    }
}

You do, however, need to be careful here. Depending on where you are running this could leave you open to script injection attacks. It would be best to scan the JS for potentially harmful script (for example any content that isn't part of a number and isn't inside quotes).

Upvotes: 1

raklos
raklos

Reputation: 28555

Did it like this:

   public class Place
    {

        public string ID { get; set; }
        public string Name { get; set; }
        public float Latitude { get; set; }
        public float Longitude { get; set; }

    }
private void Run()
{
    List<Place> places = new List<Place>();
    JObject jObject = JObject.Parse(json);
    foreach (var item in jObject)
    {
        JToken jPlace = jObject[item.Key];
        float latitude = (float)jPlace["Latitude"];
        float longitude = (float)jPlace["Longitude"];
        string name = (string)jPlace["Name"];
        places.Add(new Place { ID = item.Key, Name = name, Latitude = latitude, Longitude = longitude });

    }
}

Upvotes: 0

Zack
Zack

Reputation: 608

I'd change the format of your JSON to be something like this:

[
    {
        "PlaceID" : 1,
        "Latitude" :52.1643540,
        "Longitude" :-2.154353,
        "Name" :"AAA"
    },
    {
        "PlaceID" : 2,
        "Latitude":53.13,
        "Longitude":-2.13445,
        "Name":"BBB"
    },
    {
        "PlaceID" : 3,
        "Latitude":55.143243,
        "Longitude":-2.45234,
        "Name":"CCC"
    }
]

I'd then use the following:

public class Place
{
    public int PlaceID { get; set; }
    public float Latitude { get; set; }
    public float Longitude { get; set; }
    public string Name { get; set; }
}

To deserialize I would use:

JavaScriptSerializer serializer = new JavaScriptSerializer();
var listOfPlaces = serializer.Deserialize<List<Place>>(jsonString);

In order to use the JavaScriptSerializer you will need a reference to System.Web.Extensions.dll and using the System.Web.Script.Serialization namespace.

Upvotes: 0

Samich
Samich

Reputation: 30165

Try desearilzation. Here is the posts you might help:

C# automatic property deserialization of JSON

Parse JSON in C#

Upvotes: 0

npinti
npinti

Reputation: 52185

Have you tried using Json.NET? You can find an example on this previous SO post.

Upvotes: 2

Related Questions