ContractResolver可以实现以下操作:
自定义属性名
序列化哪些属性
CamelCasePropertyNamesContractResolver:
Newtonsoft提供了CamelCasePropertyNamesContractResolver,继承自ContractResolver,用于将属性名转成驼峰命名格式
//设置序列化时key为驼峰样式
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Demo1:自定义属性名
需求:序列化时需要将属性名以下划线分隔并小写的格式显示,如DogName序列化为dog_name
继承DefaultContractResolver,重写ResolvePropertyName方法
public class UnderlineSplitContractResolver : DefaultContractResolver
{
protected override string ResolvePropertyName(string propertyName)
{
return CamelCaseToUnderlineSplit(propertyName);
}
private string CamelCaseToUnderlineSplit(string name)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < name.Length; i++)
{
var ch = name[i];
if (char.IsUpper(ch) && i > 0)
{
var prev = name[i - 1];
if (prev != '_')
{
if (char.IsUpper(prev))
{
if (i < name.Length - 1)
{
var next = name[i + 1];
if (char.IsLower(next))
{
builder.Append('_');
}
}
}
else
{
builder.Append('_');
}
}
}
builder.Append(char.ToLower(ch));
}
return builder.ToString();
}
}
public class Person
{
public string Name { get; set; }
public string DogName { get; set; }
[JsonProperty("cat_name_1")]
public string CatName { get; set; }
}
static void Main(string[] args)
{
JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = new UnderlineSplitContractResolver()
};
Person p1 = new Person
{
Name = "fan",
DogName = "ahuang",
CatName = "nainiu"
};
var json = JsonConvert.SerializeObject(p1, settings);
Console.WriteLine(json);//输出:{"name":"fan","dog_name":"ahuang","cat_name_1":"nainiu"}
Console.ReadKey();
}
Demo2:控制属性是否序列化
根据某些场景,可能A场景输出A,B,C三个属性,B场景输出E,F属性。虽然实际中不一定存在这种需求,但是json.net依然可以支持该特性。
继承默认的DefaultContractResolver类,传入需要输出的属性,retain表示props是需要保留的字段还是要排除的字段
public class LimitPropsContractResolver : DefaultContractResolver
{
string[] props = null;
bool retain;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入的属性数组</param>
/// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param>
public LimitPropsContractResolver(string[] props, bool retain=true)
{
//指定要序列化属性的清单
this.props = props;
this.retain = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type,
MemberSerialization memberSerialization)
{
IList<JsonProperty> list =
base.CreateProperties(type, memberSerialization);
//只保留清单有列出的属性
return list.Where(p => {
if (retain)
{
return props.Contains(p.PropertyName);
}
else
{
return !props.Contains(p.PropertyName);
}
}).ToList();
}
public int Age { get; set; }
[JsonIgnore]
public bool IsMarry { get; set; }
public string Sex { get; set; }
string[] propNames = null;
if (p.Age > 10)
{
propNames = new string[] { "Age", "IsMarry" };
}
else
{
propNames = new string[] { "Age", "Sex" };
}
jsetting.ContractResolver = new LimitPropsContractResolver(propNames);
Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));