Tom Clifford
Tom Clifford

Reputation: 85

Can I Deserialize a specific field from JSON?

I am writing a method that takes a British post code and returns the Latitude and Longitude of this postcode as a "Location" object.

public class Location
{
    public double Longitude;
    public double Latitude;
}

I am using the API from https://postcodes.io/ that takes a postcode and returns a fairly large set of data about it. For example (Buckingham Palace if you're interested):

{
"status": 200,
"result": {
    "postcode": "SW1A 1AA",
    "quality": 1,
    "eastings": 529090,
    "northings": 179645,
    "country": "England",
    "nhs_ha": "London",
    "longitude": -0.141587597876975,
    "latitude": 51.5010091564599,
    "european_electoral_region": "London",
    "primary_care_trust": "Westminster",
    "region": "London",
    "lsoa": "Westminster 018C",
    "msoa": "Westminster 018",
    "incode": "1AA",
    "outcode": "SW1A",
    "parliamentary_constituency": "Cities of London and Westminster",
    "admin_district": "Westminster",
    "parish": "Westminster, unparished area",
    "admin_county": null,
    "admin_ward": "St James's",
    "ccg": "NHS Central London (Westminster)",
    "nuts": "Westminster",
    "codes": {
        "admin_district": "E09000033",
        "admin_county": "E99999999",
        "admin_ward": "E05000644",
        "parish": "E43000236",
        "parliamentary_constituency": "E14000639",
        "ccg": "E38000031",
        "nuts": "UKI32"
        }
    }
}

Currently I have set it up to get the data by generating classes for the data using Visual Studio's "Paste Special > Paste JSON as Classes" functionality and then using JSON.Net to Deserialize the whole set of data and then use the latitude and longitude from the resulting object to create a new Location object.

Rootobject locationData = JsonConvert.DeserializeObject<Rootobject>(content);

        Location locationToReturn = new Location()
        {
            Latitude = locationData.result.latitude,
            Longitude = locationData.result.longitude
        };

It seems silly to me that I have to go through the effort of Deserializing the whole thing when I only want two of the fields.

So the question is:

Can I deserialize only the latitude and longitude fields?

More specifically to my example, can I deserialize the latitude and longitude fields directly into a new instance of my Location class?

Upvotes: 4

Views: 8767

Answers (4)

Wizard
Wizard

Reputation: 171

Microsoft recommend to use System.Text.Json for security and performance reason.

// jsonDocument must be disposed, because it utilizes resources from pooled memory
using (JsonDocument jsonDocument = JsonDocument.Parse(jsonString))
{                
    JsonElement rootElement = jsonDocument.RootElement;
    JsonElement jsonElement = rootElement.GetProperty("EmployeeName");
    string employeeName = jsonElement.ToString();
}

Upvotes: 1

Brian Rogers
Brian Rogers

Reputation: 129837

You could do what you want using a JObject like this:

Location locationData = JObject.Parse(content)["result"].ToObject<Location>();

Fiddle: https://dotnetfiddle.net/vWwLUf


Alternatively just change the class definition for your Rootobject class:

class Rootobject
{
    [JsonProperty("result")]
    public Location Location { get; set; }
}

Then you can do this:

Location locationData = JsonConvert.DeserializeObject<Rootobject>(content).Location;

Fiddle: https://dotnetfiddle.net/imng8Q

Upvotes: 2

Dieter B
Dieter B

Reputation: 1142

You can load your data into a dynamic object. And then read it from there.

        dynamic locationData = JsonConvert.DeserializeObject<dynamic>(content);

        Location locationToReturn = new Location()
        {
            Latitude = locationData.result.latitude,
            Longitude = locationData.result.longitude
        };

        Console.WriteLine("Latitude: " + locationToReturn.Latitude);
        Console.WriteLine("Longitude: " + locationToReturn.Longitude);

        Console.ReadLine();

This way you can get other columns or values as well w/o enumerating through all the fields.

Upvotes: 2

Matti Price
Matti Price

Reputation: 3551

You can use Newtonsoft.Json (Json.Net) to walk through the json object yourself and only grab the values you need.

You would want to use a JObject to capture the whole result. Go to the child token of result, then grab the child items for longitude and latitude and deserialize as needed.

You can check out this answer as well How do I enumerate through a JObject?

Upvotes: 0

Related Questions