С# Манипулирование данными 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
            ]
      }
    }
  ]
}

Я пробовал JSON.Net от newtonsoft среди других, но единственное, что я могу найти:

  • чтение в объект
  • записать объект в json

Но мне не хватает шага "изменить объект". Любые подсказки?

Update

Вот что я пробовал до сих пор:

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. Я ожидал изменить значение внутри геометрии. Мне нужна ссылка, а не копия! Возможно ли это?

Update

В настоящее время я не вхожу в этот проект, но я хотел бы дать свои отзывы ответчикам. Хотя мне нравится простота Шахина, мне нравится более формальный подход L.B. Немного лучше. Мне лично не нравится использовать строковые значения в качестве функционального кода, но это только я. Если бы я мог принять оба ответа: я бы это сделал. Я думаю, что Шахин должен сделать так, чтобы "просто" поднялся.

Ответы

Ответ 1

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

Ответ 2

Если вы не хотите использовать какую-либо сущность, представляющую ваш JSON, вы можете десериализовать словарь, используя json.net и изменить словарь, а затем сериализуйте его в JSON с помощью Json.net.

Ответ 3

  • Используя Json.net, вы должны создать объекты, представляющие ваш json

  • Дезертициализируйте json в те, которые связаны как Json.Convert<FeatureCollection>(json)

  • Измените сущности

  • Преобразуйте его обратно в json.

Ответ 4

Я знаю, что это уже ответили, но я думал, что у меня есть решение, которое другие могут найти интересным.

У меня был довольно большой стробированный объект JSON, который я получил от клиента, и мне нужно было манипулировать на С#, а затем возвращать в виде строки обратно вызывающему приложению.

Не было смысла моделировать каждый аспект объекта, многие части, которые я не планировал манипулировать, менялись часто, и я не мог ожидать обновления моего приложения каждый раз, когда вызывающие изменят части своих JSON Объект Я не просил манипулировать. Поэтому я попробовал это, это немного уродливо, но все получилось хорошо:

  • Создайте класс (myClass), представляющий только раздел, который вы хотите обработать.
  • Используя Newtonsoft, создайте динамическую версию сжатого объекта JSON:

    dynamic jsonObj = JsonConvert.DeserializeObject(stringifiedJsonObject);
    
  • Создайте свой объект замены, используя класс, который вы создали выше (myClass). Затем сериализуйте этот объект, используя

    string stringPartialJsonObj = JsonConvert.SerializeObject(myClass);
    
  • Далее (и это трюк) десериализуйте только что созданный объект. Теперь это тот же тип, что и ваш источник.

    dynamic partialJsonObj = JsonConvert.Deserialize(stringPartialJsonObj);
    
  • Представьте (для этой демонстрации) в исходном объекте Json, мне нужно было изменить объект в obj.ConfigurationData.Configuration1.Data. Вот как я это сделаю:

    jsonObj.ConfigurationData.Configuration1.Data = partialJsonObj;
    
  • Наконец, я повторно сериализую все это и отправлю его пользователю:

    return JsonConvert.SerializeObject(jsonObj);
    

Это немного неуклюже, но это работает. История моей жизни: -)