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 = "";
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 = "";
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

custom serializer for just one property in Json.NET的更多相关文章

  1. js使用s:property标签接收json格式数据

    js使用s:property接收json数据时,会出现字符被转译的错误. 错误如下: 引号会被转译成'"'字符,导致解析不了. 错误原因: html的s:property接收不会出错,而js ...

  2. Extending JMeter – Creating Custom Config Element – Property File Reader

    JMeter is one of the best open source tools in the Test Automation Community. It comes with all the ...

  3. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  4. Asp MVC 中处理JSON 日期类型

    注:时间有点忙,直接copy 过来的,要查看原址: http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html I ...

  5. Json.NET Updates: Merge, Dependency Injection, F# and JSONPath Support

    Json.NET 6.0 received 4 releases this year, the latest last week. Over these releases, several new f ...

  6. Json序列化之.NET开源类库Newtonsoft.Json

    上代码: using System; using System.Collections; using System.Collections.Generic; using System.IO; usin ...

  7. JSON,全称:JavaScript Object Notation,作为一个常见的轻量级的数据交换格

    JSON,全称:JavaScript Object Notation,作为一个常见的轻量级的数据交换格式,应该在一个程序员的开发生涯中是常接触的.简洁和清晰的层次结构使得 JSON 成为理想的数据交换 ...

  8. WebApi接口 - 响应输出xml和json

    格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况:希望大家喜欢,也希望各位多多扫码支持和点 ...

  9. .Net深入实战系列—JSON序列化那点事儿

    序 当前主流的序列化JSON字符串主要有两种方式:JavaScriptSerializer及Json.net(Nuget标识:Newtonsoft.Json).JavaScriptSerializer ...

随机推荐

  1. 多次最短路反思-Holy Grail

    √ u=s[run],v=t[run]; ret=max(-d[v][u],-1000000000LL); dis[u][v]=ret;//d[u][v]= G[u].push_back(v); × ...

  2. C++解析XML字符串

    项目交互遇到了需要VC++中解析XML字符串,故花了点时间了解了下VC++中解析XML的诸多方法主要包括三种:msxml(微软提供).markup.TinyXml. 开始花了点时间使用msxml3,虽 ...

  3. JavaScript之BOM操作

    一, 什么是BOM BOM:Browser Object Model,浏览器对象模型 BOM的结构图: 从上图也可以看出: window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也 ...

  4. Codeforces - 6E - Exposition - 尺取

    https://codeforc.es/problemset/problem/6/E 既然可以多个log,那就直接map伺候.尺取之后要查询区间里面的最大值和最小值的差.众所周知尺取的时候要是不是有序 ...

  5. MVC 与 MVP 并无两样

    关于 MVC 的定义介绍,摘一段百度百科介绍: MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: Model(模型)表示应 ...

  6. 【摘】sizeof实现

    注意sizeof是运算符,而非函数 关于sizeof的两个精巧的宏实现. 非数组的sizeof: #defne _sizeof(T) ( (size_t)((T*)0 + 1)) 数组的sizeof: ...

  7. Linux安装软件-CentOS和Ubuntu介绍

    开发十年,就只剩下这套架构体系了! >>>   不同Linux发行版的软件安装会有不同的方式,其中CentOS安装软件的主要方式是rpm和yum,Ubuntu可以使用apt-get, ...

  8. 微信小程序点击保存图片到相册

    wxml部分的代码   <view class="footer-r" bindtap="save"> <image src="../ ...

  9. WPF绑定各种数据源之xml数据源

    一.WPF绑定各种数据源索引 WPF 绑定各种数据源之Datatable WPF绑定各种数据源之object数据源 WPF绑定各种数据源之xml数据源 WPF绑定各种数据源之元素控件属性 Bindin ...

  10. linux精简开机启动服务

    1.可以使用 setup-system services 里面调整,这样调整起来效率低 2.或者 ntsysv 调出来 3.使用脚本一件关闭 #LANG=en chkconfig --list #停止 ...