Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Manipulating JSON data

Tags:

json

c#

json.net

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.

like image 754
Nebula Avatar asked Jun 15 '12 09:06

Nebula


2 Answers

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

like image 34
Capt. Rochefort Avatar answered Oct 06 '22 01:10

Capt. Rochefort


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();
like image 85
L.B Avatar answered Oct 05 '22 23:10

L.B