Remove fields from JSON dynamically using Json.Net(使用 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 中动态删除字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Json.Net 从 JSON 中动态删除字段
基础教程推荐
- rabbitmq 的 REST API 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- SSE 浮点算术是否可重现? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01