custom serializer for just one property in Json.NET
Json序列化的时候跳过加密字段
public class Field { public bool IsEncrypted { get; set; } public string Name { get; set; } public Object Value { get; set; } }
需要序列化User类
public class User { public Field UserName { get; set; } public Field Password { get; set; } }
序列化的结果,加密字段密码也被序列化出来了
[Test] public void TestChuck() { User user = new User(); Field field = new Field(); field.IsEncrypted = false; field.Name = "UserName"; field.Value = "chucklu"; user.UserName = field; field = new Field(); field.IsEncrypted = true; field.Name = "Password"; field.Value = "123456"; user.Password = field; string str = JsonConvert.SerializeObject(user); Console.WriteLine(str); }
{
"UserName": {
"IsEncrypted": false,
"Name": "UserName",
"Value": "chucklu"
},
"Password": {
"IsEncrypted": true,
"Name": "Password",
"Value": "123456"
}
}
https://stackoverflow.com/questions/18521970/custom-serializer-for-just-one-property-in-json-net
You can add a custom serializer to a single attribute like this:
public class Comment
{
public string Author { get; set; }
[JsonConverter(typeof(NiceDateConverter))]
public DateTime Date { get; set; }
public string Text { get; set; }
}
public class NiceDateConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var date = value as DateTime;
var niceLookingDate = date.ToString("MMMM dd, yyyy 'at' H:mm tt");
writer.WriteValue(niceLookingDate);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime);
}
}
Then, when you serialize your object with JsonConvert.SerializeObject(), the custom serializer will be used for the Date property.
解决方案
继承JsonConverter实现自定义的Converter,FieldConverter,然后在属性上添加[JsonConverter(typeof(FieldConverter))]
public class User { public Field UserName { get; set; } [JsonConverter(typeof(FieldConverter))] public Field Password { get; set; } } public class Field { public bool IsEncrypted { get; set; } public string Name { get; set; } public object Value { get; set; } }
public class FieldConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is Field field && !field.IsEncrypted) { var str = JsonConvert.SerializeObject(value); writer.WriteValue(str); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanConvert(Type objectType) { return objectType == typeof(Field); } }
输出结果是
{
"UserName": {
"IsEncrypted": false,
"Name": "UserName",
"Value": "chucklu"
},
"Password": null
}
类似的,如果Field 这样使用List<Field>
public class User { public List<Field> list = new List<Field>(); } public class Field { public bool IsEncrypted { get; set; } public string Name { get; set; } public object Value { get; set; } }
[Test] public void TestChuck() { User user = new User(); Field field = new Field(); field.IsEncrypted = false; field.Name = "UserName"; field.Value = "chucklu"; user.list.Add(field); field = new Field(); field.IsEncrypted = true; field.Name = "Password"; field.Value = "123456"; user.list.Add(field); string str = JsonConvert.SerializeObject(user); Console.WriteLine(str); }
输出是
{
"list": [
{
"IsEncrypted": false,
"Name": "UserName",
"Value": "chucklu"
},
{
"IsEncrypted": true,
"Name": "Password",
"Value": "123456"
}
]
}
方案
唯一的问题是,把转义的双引号打出来了 使用 writer.WriteRawValue(str);可以避免json字符串被内部转义
public class FieldConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is List<Field> list) { var temp = list.Where(x => !x.IsEncrypted).ToList(); var str = JsonConvert.SerializeObject(temp); writer.WriteValue(str);
writer.WriteRawValue(str); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanConvert(Type objectType) { return objectType == typeof(List<Field>); } }
{"list":"[{\"IsEncrypted\":false,\"Name\":\"UserName\",\"Value\":\"chucklu\"}]"} 本来[]两边是没有双引号的,里面的转义也是多出来的
{"List":[{"IsEncrypted":false,"Name":"UserName","Value":"chucklu"}]} 必须是 writer.WriteRawValue(str);
如果是 writer.WriteRaw(str);的话,结果中会多出一个null
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-06-19 NPOI设置Excel中的单元格识别为日期
2017-06-19 FileStream vs/differences StreamWriter?
2017-06-19 Excel显示当前日期
2015-06-19 编程概念--使用async和await的异步编程
2014-06-19 Winform中使用折叠窗口