Элегантный способ замены / редактирования указанного c JSON текста в файле? - PullRequest
0 голосов
/ 05 мая 2020

Предположим, у меня есть текстовый файл JSON, в котором есть несколько элементов .. Мне нужно отредактировать в нем указанный c элемент, добавив к нему еще одну пару ключ / значение. Это изменение необходимо сделать только для указанного c элемента в файле JSON, а не для других элементов в этом текстовом файле. Кроме того, изменение должно выдерживать будущие изменения любых других частей текстового файла.

Например, предположим, что текстовый файл имеет такие записи (... означает больше похожих записей):

{
    "Blah": "Blah",
    "Blah": "Blah",
    "Blah": "Blah",
    "Blah": "Blah",
    "TopologyResources": [
        .....
        ,
        {
          "ResourceUri": "https://proto23.devspace.com/merger",
          "ActAsPrivileges": [
            "UserData.Read",
            "UserData.ReadWrite"
          ],
          "AppOnlyPrivileges": [
            "UserData.Read",
            "UserData.ReadWrite",
            "UserMeetingData-Internal.ReadWrite"
          ]
        },
        .....
    ]
}

Я хочу изменить приведенное выше на это (обратите внимание на добавление ключа GlobalTopologyAccessScopes:

{
    "Blah": "Blah",
    "Blah": "Blah",
    "Blah": "Blah",
    "Blah": "Blah",
    "TopologyResources": [
        .....
        ,
        {
          "ResourceUri": "https://proto23.devspace.com/merger",
          "ActAsPrivileges": [
            "UserData.Read",
            "UserData.ReadWrite"
          ],
          "AppOnlyPrivileges": [
            "UserData.Read",
            "UserData.ReadWrite",
            "UserMeetingData-Internal.ReadWrite"
          ],
          "GlobalTopologyAccessScopes": [
            {
              "ScopeType": "Dev",
              "AccessType": "All"
            }
          ]
        },
        .....
    ]
}   

Есть ли какой-либо более элегантный способ сделать это изменение, кроме кода ниже что выглядит уродливо?

string originalText = File.ReadAllText(filepath);

            string find = "    {\r\n      \"ResourceUri\": \"https://proto23.devspace.com/merger\",\r\n      \"ActAsPrivileges\": [\r\n        \"UserData.Read\",\r\n        \"UserData.ReadWrite\"\r\n      ],\r\n      \"AppOnlyPrivileges\": [\r\n        \"UserData.Read\",\r\n        \"UserData.ReadWrite\",\r\n        \"UserMeetingData-Internal.ReadWrite\"\r\n      ]\r\n    }";
            string replace = "    {\r\n      \"ResourceUri\": \"https://proto23.devspace.com/merger\",\r\n      \"ActAsPrivileges\": [\r\n        \"UserData.Read\",\r\n        \"UserData.ReadWrite\"\r\n      ],\r\n      \"AppOnlyPrivileges\": [\r\n        \"UserData.Read\",\r\n        \"UserData.ReadWrite\",\r\n        \"UserMeetingData-Internal.ReadWrite\"\r\n      ],\r\n      \"GlobalTopologyAccessScopes\": [\r\n        {\r\n          \"ScopeType\": \"Dev\",\r\n          \"AccessType\": \"All\"\r\n        }\r\n      ]\r\n    }";

            newText = originalText.Replace(find, replace);
            File.WriteAllText(filepath, newText);

Примечание. Если вы думаете о десериализации данных JSON в класс C#, внесите изменения, а затем снова напишите сериализованную версию. Позвольте мне сказать вам, что не существует класса C# для десериализации данных json в ..

EDIT: В основном объект уровня root имеет ключ с именем TopologyResources, который является массив .. Ключ GlobalTopologyAccessScopes необходимо добавить к этому объекту в массиве TopologyResources, который имеет ResourceUri: https://proto23.devspace.com/merger

1 Ответ

1 голос
/ 06 мая 2020

Добавление моего окончательного решения, основанного на удаленном ответе Павла, но с некоторыми изменениями. Поскольку Павел удалил свой ответ, я не могу проголосовать за его ответ.

В любом случае, это то, что я сделал:

string filepath = @"C:\SomeFolder\someFile.xyz";
string originalText = File.ReadAllText(filepath);

JObject json = JObject.Parse(originalText);

if (json["TopologyResources"] is JArray resources)
{
    JObject correctObject = resources.Children<JObject>()
        .FirstOrDefault(pq => pq["ResourceUri"].ToString() == @"https://proto23.devspace.com/merger");

    if (correctObject != null)
    {
        var scopeDetail = new[] { new { ScopeType = "Dev", AccessType = "All" } };
        correctObject.Add("GlobalTopologyAccessScopes", JArray.FromObject(scopeDetail));
    }
}

var changedText = json.ToString();
File.WriteAllText(filepath, changedText);

Надеюсь, другие сочтут его полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...