C#操作JSON数据

时间:2012-06-15 09:09:48

标签: c# json json.net

我有一个'简单'场景:读取一些JSON文件,过滤或更改一些值,然后将结果写回json,而不更改原始格式。

所以例如改变这个:

{
  "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
            ]
          ]
        ]
      }
    }
  ]
}

进入这个:

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

我已经尝试过newtonsoft等JSON.Net,但我唯一能找到的就是:

  • 读入对象
  • 将对象写入json

但我错过了'改变对象'的步骤。任何提示?

更新

这是我到目前为止所尝试的内容:

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";
}

但这只会改变geoType变量的值。我希望也可以更改里面的值。我需要一个参考,而不是副本!这可能吗?

更新

我目前正在离开这个项目,但我想向回答者提供反馈。虽然我喜欢沙欣的简单,但我喜欢L.B.的更正式的方法。好一点。我个人不喜欢使用字符串值作为功能代码,但那只是我。如果我能接受这两个答案:我愿意。我想沙欣将不得不用'只是'一个upvote做出应有的结果。

4 个答案:

答案 0 :(得分:14)

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();

答案 1 :(得分:1)

如果您不想使用任何代表您的JSON的实体,您可以使用json.net反序列化为Dictionary并修改字典,然后使用Json.net将其序列化为JSON。

答案 2 :(得分:0)

  1. 使用Json.net您必须创建代表json

    的实体
  2. json反序列化为Json.Convert<FeatureCollection>(json)

  3. 等内容
  4. 更改实体

  5. 将其转换回json

答案 3 :(得分:0)

我知道这已经得到了解答,但我认为我有一个别人可能会感兴趣的解决方案。

我有一个非常大的字符串化JSON对象,我从客户那里收到并需要在C#中操作,然后以字符串形式返回给调用应用程序。

对对象的每个方面进行建模没有任何意义,我不打算进行操作的很多部分经常发生变化,而且每次都不能更新我的应用程序。调用者修改了他们的JSON对象的部分我没有被要求操纵。所以我尝试了这个,它有点难看,但效果很好:

  1. 创建一个类(myClass),表示只是您想要操作的部分。
  2. 使用Newtonsoft,创建字符串化JSON对象的动态版本:

    dynamic jsonObj = JsonConvert.DeserializeObject(stringifiedJsonObject);
    
  3. 使用您在上面创建的类(myClass)构建替换对象。然后使用

    序列化该对象
    string stringPartialJsonObj = JsonConvert.SerializeObject(myClass);
    
  4. 接下来,(这就是技巧)反序列化刚刚创建的对象。现在它与您的来源类型相同。

    dynamic partialJsonObj = JsonConvert.Deserialize(stringPartialJsonObj);
    
  5. 想象一下(为了这个演示)在原始的Json对象中,我需要修改obj.ConfigurationData.Configuration1.Data中的对象。我就是这样做的:

    jsonObj.ConfigurationData.Configuration1.Data = partialJsonObj;
    
  6. 最后,我重新序列化整个事情并将其发回给用户:

    return JsonConvert.SerializeObject(jsonObj);
    
  7. 它有点笨重,但它有效。我生命的故事: - )