17

我有一个“简单”的场景:读取一些 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 变量的值。我也希望改变几何内部的值。我需要参考,而不是副本!这可能吗?

更新

我目前不在这个项目中,但我想向回答者提供我的反馈。虽然我喜欢 Shahin 的简单性,但我更喜欢 LB 更正式的方法。我个人不喜欢使用字符串值作为功能代码,但这只是我。如果我能接受这两个答案:我愿意。我猜沙欣将不得不“仅仅”投赞成票。

4

4 回答 4

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();
于 2012-06-15T10:30:38.047 回答
2

我知道这已经得到解答,但我认为我有一个其他人可能会觉得有趣的解决方案。

我从客户那里收到了一个非常大的字符串化 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);
    

这有点笨拙,但它确实有效。我的生活故事:-)

于 2017-09-07T04:21:25.793 回答
1

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

于 2012-06-15T09:32:43.307 回答
0
  1. 使用Json.net你必须创建代表你的实体json

  2. 反序列json化成那些实体,比如Json.Convert<FeatureCollection>(json)

  3. 更改实体

  4. 将其转换回json.

于 2012-06-15T09:13:55.623 回答