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