首页 > 解决方案 > 更新 JSON 文件中的特定值

问题描述

我正在寻找一种通过名称查找特定 json 值并将其值设置为 null 的方法。json文件的构造可以是任何东西,并不总是一样的。

假设 json 看起来像这样:

[
{
    "id": "1111",
    "email": "email@email.com",
},
{
    "id": "2222",
    "email": "email2@email2.com",
}]

我正在寻找的结果是这样的:

[
{
    "id": "1111",
    "email": null,
},
{
    "id": "2222",
    "email": null,
}]

当对象更复杂时,它也应该起作用。

{
"reservations": [
    {
        "id": "111",
        "bookingId": "",
        "status": "",
        "checkInTime": "",
        "checkOutTime": "",
        "property": {
            "id": "",
            "code": "",
            "name": "",
        },
        "primaryGuest": {
            "firstName": "",
            "middleInitial": "",
            "lastName": "",
            "email": "email@email.com",
            "phone": "",
            "address": {
                "addressLine1": "",
                "postalCode": "",
                "city": "",
                "countryCode": ""
            }
        },
        "booker": {
            "firstName": "",
            "middleInitial": "",
            "lastName": "",
            "email": "email2@email.com",
            "phone": ""
        }
   }]}

我尝试过使用 JArray、JObject 类等,但它仅在propety["email"] 是第一个孩子而不是更深的情况下才有效。不知道如何做到这一点。

 private JObject HashSensitiveData(JContainer jContainer)
    {
        if (!jContainer.Descendants().Any())
        {
            return null;
        }

        var objects = jContainer.Descendants().OfType<JObject>();

        foreach (var property in objects)
        {
            foreach (var emailProperty in property.Properties().Where(x => x.Name.CaseInsensitiveContains(LoggerHashedProperties.Email.ToString())))
            {
                var email = emailProperty.Value.ToString();
                property[emailProperty.Name] =null
            }
        }

        return HashSensitiveData(jContainer);
    }

标签: c#json.netlinq

解决方案


使用 NewtonSoft,我曾经做了一个 flatten 函数来分析任何深度的 json 文件:

IEnumerable<JProperty> Flatten(JToken token)
{
    return token.Children<JProperty>().Concat(
        token.Children().SelectMany(t => Flatten(t)))
        .Where(t => t.Value is JValue);
}

它返回文件中所有“端点”的平面列表JsonProperty(例如:所有"xyx" : primitive value条目)。使用它,您可以简单地反序列化您的 Json,找到所有“电子邮件”属性并将其值设置为null

var jobj = JsonConvert.DeserializeObject<JObject>(getJson());

var flattened = Flatten(jobj);

foreach (var jprop in flattened.Where(t => t.Name == "email"))
{
    jprop.Value = null;
}
var json = JsonConvert.SerializeObject(jobj).Dump();

“更复杂”的 json 的结果(添加了一封更深入的电子邮件以使其更有趣):

{
  "reservations": [
    {
      "id": "111",
      "bookingId": "",
      "status": "",
      "checkInTime": "",
      "checkOutTime": "",
      "property": {
        "id": "",
        "code": "",
        "name": ""
      },
      "primaryGuest": {
        "firstName": "",
        "middleInitial": "",
        "lastName": "",
        "email": null,
        "phone": "",
        "address": {
          "email": null,
          "addressLine1": "",
          "postalCode": "",
          "city": "",
          "countryCode": ""
        }
      },
      "booker": {
        "firstName": "",
        "middleInitial": "",
        "lastName": "",
        "email": null,
        "phone": ""
      }
    }
  ]
}

推荐阅读