web-dev-qa-db-ja.com

C#JSONデータの操作

「単純な」シナリオがあります。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変数の値を変更するだけです。値insideジオメトリも変更することを期待していました。コピーではなく、参照が必要です!これは可能ですか?

更新

私は現在このプロジェクトを離れていますが、回答者にフィードバックを送りたいと思います。 Shahinのシンプルさが好きですが、L.B。のより正式なアプローチが好きです。少し良く。私は個人的に関数型コードとして文字列値を使用するのは好きではありませんが、それは私だけです。私が両方の答えを受け入れることができれば:私はそうします。 Shahinは、「ただ」の賛成で期限を迎える必要があると思います。

17
Nebula
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();
14
L.B

私はこれがすでに答えられていることを知っていますが、他の人が面白いと思うかもしれない解決策があると思いました。

顧客から受け取ったかなり大きな文字列化されたJSONオブジェクトがあり、C#で操作してから、文字列形式で呼び出し元のアプリケーションに戻す必要がありました。

オブジェクトのすべての側面をモデル化することは意味がありませんでした。操作する予定がなかった多くの部分が頻繁に変更され、呼び出し元がJSONオブジェクトの一部を変更するたびにアプリケーションを更新することは期待できませんでした。操作を求められていません。だから私はこれを試しました、それは少し醜いですが、それはうまくいきました:

  1. 操作するセクションを表すクラス(myClass)を作成しますjust
  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);
    

少し不格好ですが、機能します。私の人生談 :-)

1
Capt. Rochefort

JSONを表すエンティティを使用したくない場合は、json.netを使用してDictionaryに逆シリアル化し、辞書を変更してから、Json.netを使用してJSONにシリアル化できます。

1
Shahin
  1. _Json.net_を使用して、jsonを表すエンティティを作成する必要があります

  2. jsonJson.Convert<FeatureCollection>(json)のようなエンティティに逆シリアル化します

  3. エンティティを変更する

  4. jsonに変換し直します。

0
Asif Mushtaq