使用 Json.Net 从 JSON 中动态删除字段 [英] Remove fields from JSON dynamically using Json.Net

查看:23
本文介绍了使用 Json.Net 从 JSON 中动态删除字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 JSON 输入,我无法预测其形状,我必须进行一些转换(称之为某种东西),以便不记录某些字段.例如,如果我有这个 JSON:

I have some JSON input, the shape of which I cannot predict, and I have to make some transformations (to call it something) so that some fields are not logged. For instance, if I have this JSON:

{
    "id": 5,
    "name": "Peter",
    "password": "some pwd"
}

那么在转换之后应该是这样的:

then after the transformation it should look like this:

{
    "id": 5,
    "name": "Peter"
}  

上面的示例是微不足道的,但实际情况并不那么快乐/容易.我将有一些正则表达式,如果 input JSON 上的任何字段匹配,那么它不应该出现在结果中.如果我有一些嵌套对象,我将不得不递归.我在 LINQ to JSON 上看到了一些东西,但我没有发现任何东西能满足我的需求.

The above sample is trivial, but the actual case is not so happy/easy. I will have some regular expressions and if any field(s) on the input JSON matches that, then it shouldn't be on the result. I will have to go recursively in case I have some nested objects. I've been seeing some stuff on LINQ to JSON but I have found nothing satisfying my needs.

有没有办法做到这一点?

Is there a way of doing this?

注意:这是日志库的一部分.如果需要或更简单,我可以使用 JSON 字符串.问题是,在我的日志记录管道中的某个时刻,我获取了对象(或需要的字符串),然后我需要从中删除敏感数据,例如 passwords,以及任何其他客户端-指定数据.

Note: This is part of a logging library. I can use the JSON string if necessary or easier. The thing is that at some point in my logging pipeline I get the object (or string as required) and then I need to strip the sensitive data from it, such as passwords, but also any other client-specified data.

推荐答案

您可以将 JSON 解析为 JToken,然后使用递归辅助方法将属性名称与正则表达式匹配.只要有匹配项,您就可以从其父对象中删除该属性.删除所有敏感信息后,只需使用 JToken.ToString() 即可获取编辑后的 ​​JSON.

You can parse your JSON into a JToken, then use a recursive helper method to match property names to your regexes. Wherever there's a match, you can remove the property from its parent object. After all sensitive info has been removed, just use JToken.ToString() to get the redacted JSON.

下面是帮助方法的样子:

Here is what the helper method might look like:

public static string RemoveSensitiveProperties(string json, IEnumerable<Regex> regexes)
{
    JToken token = JToken.Parse(json);
    RemoveSensitiveProperties(token, regexes);
    return token.ToString();
}

public static void RemoveSensitiveProperties(JToken token, IEnumerable<Regex> regexes)
{
    if (token.Type == JTokenType.Object)
    {
        foreach (JProperty prop in token.Children<JProperty>().ToList())
        {
            bool removed = false;
            foreach (Regex regex in regexes)
            {
                if (regex.IsMatch(prop.Name))
                {
                    prop.Remove();
                    removed = true;
                    break;
                }
            }
            if (!removed)
            {
                RemoveSensitiveProperties(prop.Value, regexes);
            }
        }
    }
    else if (token.Type == JTokenType.Array)
    {
        foreach (JToken child in token.Children())
        {
            RemoveSensitiveProperties(child, regexes);
        }
    }
}

这里有一个简短的使用演示:

And here is a short demo of its use:

public static void Test()
{
    string json = @"
    {
      ""users"": [
        {
          ""id"": 5,
          ""name"": ""Peter Gibbons"",
          ""company"": ""Initech"",
          ""login"": ""pgibbons"",
          ""password"": ""Sup3rS3cr3tP@ssw0rd!"",
          ""financialDetails"": {
            ""creditCards"": [
              {
                ""vendor"": ""Viza"",
                ""cardNumber"": ""1000200030004000"",
                ""expDate"": ""2017-10-18"",
                ""securityCode"": 123,
                ""lastUse"": ""2016-10-15""
              },
              {
                ""vendor"": ""MasterCharge"",
                ""cardNumber"": ""1001200230034004"",
                ""expDate"": ""2018-05-21"",
                ""securityCode"": 789,
                ""lastUse"": ""2016-10-02""
              }
            ],
            ""bankAccounts"": [
              {
                ""accountType"": ""checking"",
                ""accountNumber"": ""12345678901"",
                ""financialInsitution"": ""1st Bank of USA"",
                ""routingNumber"": ""012345670""
              }
            ]
          },
          ""securityAnswers"":
          [
              ""Constantinople"",
              ""Goldfinkle"",
              ""Poppykosh"",
          ],
          ""interests"": ""Computer security, numbers and passwords""
        }
      ]
    }";

    Regex[] regexes = new Regex[]
    {
        new Regex("^.*password.*$", RegexOptions.IgnoreCase),
        new Regex("^.*number$", RegexOptions.IgnoreCase),
        new Regex("^expDate$", RegexOptions.IgnoreCase),
        new Regex("^security.*$", RegexOptions.IgnoreCase),
    };

    string redactedJson = RemoveSensitiveProperties(json, regexes);
    Console.WriteLine(redactedJson);
}

这是结果输出:

{
  "users": [
    {
      "id": 5,
      "name": "Peter Gibbons",
      "company": "Initech",
      "login": "pgibbons",
      "financialDetails": {
        "creditCards": [
          {
            "vendor": "Viza",
            "lastUse": "2016-10-15"
          },
          {
            "vendor": "MasterCharge",
            "lastUse": "2016-10-02"
          }
        ],
        "bankAccounts": [
          {
            "accountType": "checking",
            "financialInsitution": "1st Bank of USA"
          }
        ]
      },
      "interests": "Computer security, numbers and passwords"
    }
  ]
}

小提琴:https://dotnetfiddle.net/KcSuDt

这篇关于使用 Json.Net 从 JSON 中动态删除字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆