我们经常在生产当中需要根据不同的场景需求使用Json.NET(Newtonsoft.Json) 提供不同的API数据结构,例如某个对象当中其中几项不能对外(API)提供数据展示,但是需要对内部(API)系统提供展示,这个时候我们可能为此建立多个不同的业务实体进行相应的赋值然后进行序列化来解决这个问题;其实 Json.NET(Newtonsoft.Json) 为我们做了相应的功能(如:通过JsonIgnore / JsonProperty 特性)来处理,可是这个不能满足我们的需求,但是Json.NET(Newtonsoft.Json)提供了一些高级功能,通过继承 DefaultContractResolver 重写 CreateProperties 方法来实现,我将实现的代码贴出来,希望对大家有所帮助
/// <summary>
/// 属性选项
/// Add by 成长的小猪(Jason.Song) on 2017/08/01
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
public enum PropertyOption
{
/// <summary>
/// 包含/展示 某些属性
/// </summary>
Include,
/// <summary>
/// 排除/隐藏 某些属性
/// </summary>
Exclude
}
/// <inheritdoc />
/// <summary>
/// 属性展示设置
/// 设置包含某个属性或排除某个属性
/// Add by 成长的小猪(Jason.Song)on 2017/08/01
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
public class PropertyDisplayResolver : DefaultContractResolver
{
private readonly PropertyOption _propertyOption;
private readonly IEnumerable<string> _propertyNames;
/// <inheritdoc />
/// <summary>
/// 初始化实例
/// Add by 成长的小猪(Jason.Song) on 2017/08/01
/// </summary>
/// <param name="propertyOption">属性选项:Include包含/Exclude排除</param>
/// <param name="propertyNames">属性名称列表</param>
public PropertyDisplayResolver(PropertyOption propertyOption, IEnumerable<string> propertyNames) {
_propertyOption = propertyOption;
_propertyNames = propertyNames;
}
/// <inheritdoc />
/// <summary>
/// 初始化实例
/// Add by 成长的小猪(Jason.Song) on 2017/08/01
/// </summary>
/// <param name="propertyOption">属性选项:Include包含/Exclude排除</param>
/// <param name="propertyNames">属性名称</param>
public PropertyDisplayResolver(PropertyOption propertyOption, params string[] propertyNames) {
_propertyOption = propertyOption;
_propertyNames = propertyNames;
}
/// <inheritdoc />
/// <summary>
/// 重写 DefaultContractResolver 里的 CreateProperties创建属性方法
/// Add by 成长的小猪(Jason.Song) on 2017/08/01
/// Creates properties for the given <see cref="T:Newtonsoft.Json.Serialization.JsonContract" />.
/// </summary>
/// <param name="type">The type to create properties for.</param>
/// <param name="memberSerialization">The member serialization mode for the type.</param>
/// <returns>Properties for the given <see cref="T:Newtonsoft.Json.Serialization.JsonContract" />.</returns>
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
var properties = base.CreateProperties(type, memberSerialization).ToList();
//此处进行筛选
return _propertyOption == PropertyOption.Include ? properties.FindAll(p => _propertyNames.Contains(p.PropertyName))
: properties.FindAll(p => !_propertyNames.Contains(p.PropertyName));
}
}
以下是使用方法和测试的代码
/// <summary>
/// 用户实体(测试)
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
public class User
{
/// <summary>
/// 用户ID
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string Username { get; set; }
/// <summary>
/// 密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 真实姓名
/// </summary>
public string Realname { get; set; }
}
/// <summary>
/// Json.NET(Newtonsoft.Json) 特殊场景使用方法
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
[TestFixture()]
public class PropertyDisplayResolverTests
{
[Test()]
public void PropertyDisplayResolverTest() {
//测试实体数据
var user = new User
{
UserId = 8888,
Username = "jason",
Password = "jasonsong",
Realname = "成长的小猪"
};
//正常情况下转换对象为Json字符串
//var json = JsonConvert.SerializeObject(user);
//输出的结果为:
//{"UserId":8888,"Username":"jason","Password":"jasonsong","Realname":"成长的小猪"}
//如果我们不希望展示 Password 密码属性,可以使用排除选项 PropertyOption.Exclude
//var json = JsonConvert.SerializeObject(user, new JsonSerializerSettings {
// ContractResolver = new PropertyDisplayResolver(PropertyOption.Exclude, "Password")
//});
//输出的结果为:
//{"UserId":8888,"Username":"jason","Realname":"成长的小猪"}
//如果我们只想输出用户名 Username 和 Realname 属性,可以使用包含选项 PropertyOption.Include
var json = JsonConvert.SerializeObject(user, new JsonSerializerSettings {
ContractResolver = new PropertyDisplayResolver(PropertyOption.Include, "Username", "Realname")
});
//输出的结果为:
//{"Username":"jason","Realname":"成长的小猪"}
Assert.Warn(json);
}
}