问题描述
我有一些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动态删除字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!