17

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:

  • read into object
  • write object to json

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.

Nebula
  • 1,045
  • 2
  • 11
  • 24
  • 1
    I haven't actually worked through this, but it seems like the dynamic type would be useful for this. See here: http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object – McGarnagle Jun 15 '12 at 09:22

4 Answers4

16
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();
L.B
  • 114,136
  • 19
  • 178
  • 224
2

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 :-)

Rob
  • 26,989
  • 16
  • 82
  • 98
Capt. Rochefort
  • 716
  • 1
  • 10
  • 17
1

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.

Shahin
  • 117
  • 4
0
  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.

Asif Mushtaq
  • 13,010
  • 3
  • 33
  • 42
  • Thank you, but this I knew. I'd like to skip the phase of needing to create my own object and edit the deserialized data directly. – Nebula Jun 15 '12 at 09:20
  • why you try deserialize json into dynamics using json.net and then change it? – Asif Mushtaq Jun 15 '12 at 09:25
  • I'd like to note that any elements in the JSON file not present in the provided type will remain null and when the object is written back to JSON data any null objects will be left out. – MrFox Apr 07 '21 at 08:44