我有一些JSON输入,其形状我无法预测,并且我必须进行一些转换(以称呼它),以便不记录某些字段。例如,如果我有此JSON:
{ "id": 5, "name": "Peter", "password": "some pwd" }
然后,在转换之后,它应如下所示:
{ "id": 5, "name": "Peter" }
上面的示例是微不足道的,但实际情况并非如此。我将有一些正则表达式,如果 输入JSON 上的任何字段与之匹配,则不应将其放在结果上。如果我有一些嵌套对象,我将必须递归进行。我一直在 LINQ to JSON 上看到过一些东西,但找不到满足我需求的东西。
有办法吗?
注意 :这是日志记录库的一部分。如果有必要或更简单,我可以使用JSON字符串。问题是,在日志记录管道的某个时刻,我得到了对象(或所需的字符串),然后需要从中剥离敏感数据,例如 密码 ,以及其他任何客户端指定的数据。
您可以将JSON解析为JToken,然后使用递归帮助器方法将属性名称与正则表达式进行匹配。只要有匹配项,就可以从其父对象中删除该属性。删除所有敏感信息后,只需使用JToken.ToString()即可获取已编辑的JSON。
JToken
JToken.ToString()
这是辅助方法的外观:
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); } } }
这是其用法的简短演示:
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