Nebula
Nebula

Reputation: 1056

C# Manipulating JSON data

I have a 'simple' scenario: Read some JSON file, Filter or change some of the values and write the resulting json back without changing the original formatting.

So for example to change this:

{
  "type": "FeatureCollection",
  "crs": {
    "type": "EPSG",
    "properties": {
      "code": 28992
    }
  },
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              149886.192,
              374554.705
            ],
            [
              149728.583,
              374473.112
            ],
            [
              149725.476,
              374478.215
            ]
          ]
        ]
      }
    }
  ]
}

Into this:

{
  "type": "FeatureCollection",
  "crs": {
    "type": "EPSG",
    "properties": {
      "code": 28992
    }
  },
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": 
            [
              149886.192,
              374554.705
            ]
      }
    }
  ]
}

I've tried JSON.Net by newtonsoft among others but the only this I can find is:

But I'm missing the 'change the object' step. Any hints?

Update

Here's what I've tried so far:

JToken contourManifest = JObject.Parse(input);

JToken features = contourManifest.SelectToken("features");

for (int i = 0; i < features.Count(); i++)
{
    JToken geometry = features[i].SelectToken("geometry");
    JToken geoType = geometry.SelectToken("type");
    JToken coordinates = geometry.SelectToken("coordinates");

    geoType = "Point";
}

But this only changes the value of the geoType variable. I'd expected to change the value inside the geometry as well. I need a reference, not a copy! Is this possible?

Update

I am currently off this project but I'd like to give my feedback to the answerers. Though I like the simplicity of Shahin, I like the more formal approach of L.B. a bit better. I personally don't like using string values as functional code, but that's just me. If I could accept both answers: I would. I guess Shahin wil have to make due with 'just' an upvote.

Upvotes: 17

Views: 29705

Answers (4)

Capt. Rochefort
Capt. Rochefort

Reputation: 726

I know this has already been answered but I thought I had a solution others might find interesting.

I had a pretty large stringified JSON object that I received from a customer and needed to manipulate in C# and then return in string form back to the calling application.

It didn't make sense to model every aspect of the object, many parts that I wasn't planning on manipulating were changing often and I couldn't be expected to update my application every time the caller modified portions of their JSON object I wasn't being asked to manipulate. So I tried this, it's a bit ugly but it worked well:

  1. Create a class (myClass) representing just the section you want to manipulate.
  2. Using Newtonsoft, create a dynamic version of the stringified JSON object:

    dynamic jsonObj = JsonConvert.DeserializeObject(stringifiedJsonObject);
    
  3. Build your replacement object using the class you created above (myClass). Then serialize that object using

    string stringPartialJsonObj = JsonConvert.SerializeObject(myClass);
    
  4. Next, (and this is the trick) deserialize the object you just created. Now it's the same type as your source.

    dynamic partialJsonObj = JsonConvert.Deserialize(stringPartialJsonObj);
    
  5. Imagine (for the sake of this demonstration) in the original Json object, I needed to modify the object in obj.ConfigurationData.Configuration1.Data. This is how I'd do it:

    jsonObj.ConfigurationData.Configuration1.Data = partialJsonObj;
    
  6. Finally, I'd re-serialize the whole thing and send it back to the user:

    return JsonConvert.SerializeObject(jsonObj);
    

It's a bit clunky, but it works. Story of my life :-)

Upvotes: 2

L.B
L.B

Reputation: 116178

dynamic contourManifest = JObject.Parse(input);
foreach (var feature in contourManifest.features)
{
    feature.geometry.Replace(
            JObject.FromObject(
                        new { 
                            type = "Point", 
                            coordinates = feature.geometry.coordinates[0][0] 
                        }));
}

var newJson = contourManifest.ToString();

Upvotes: 16

Shahin
Shahin

Reputation: 127

If you don't want using any entity that representing your JSON, you can deserialize to Dictionary by using json.net and modify dictionary, then serialize it to JSON by using Json.net.

Upvotes: 2

Asif Mushtaq
Asif Mushtaq

Reputation: 13150

  1. Using Json.net you have to create the entities representing your json

  2. Deserialize the json into those enties like Json.Convert<FeatureCollection>(json)

  3. Change the entities

  4. Convert it back to json.

Upvotes: 0

Related Questions