Newtonsoft.Json笔记
序列化设置的几种方式:
全局序列化:(在之后使用JsonConvert进行序列化时都有效)
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
//日期类型默认格式化处理
setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
setting.DateFormatString = "yyyy-MM--dd HH:mm:ss";
//空值处理
setting.NullValueHandling = NullValueHandling.Ignore;
//setting.Converters.Add(new BoolConvert("是,否"));
return setting;
});
序列化时指定JsonSerializerSettings:
JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.DefaultValueHandling = DefaultValueHandling.Ignore;
jsetting.DateFormatString = "yyyy-MM---dd HH:mm:ss";
Man2 man = new Man2
{
Name = "张三",
DogName = "阿黄",
Birthday = DateTime.Now
};
//new JsonConverter().
string json = JsonConvert.SerializeObject(man, jsetting);
通过特性标签设置:
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
public Room room { get; set; }
忽略某些属性
通过在属性上添加[JsonIgnore]标签可以忽略序列化属性
也可以设置仅序列化某些属性:
[JsonObject(MemberSerialization.OptIn)]
public class Person
{
[JsonProperty]
public string Name { get; set; }
public string Sex { get; set; }
}
默认值处理
DefaultValueHandling.Ignore 序列化和反序列化时,忽略默认值
DefaultValueHandling.Include 序列化和反序列化时,包含默认值
JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.DefaultValueHandling = DefaultValueHandling.Ignore;//忽略默认值
空值处理
方式1:
JsonSerializerSettings jsetting=new JsonSerializerSettings();
jsetting.NullValueHandling = NullValueHandling.Ignore;//忽略空值
方式2:
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
public Room room { get; set; }
支持非公共成员
序列化时默认都是只处理公共成员,如果需要处理非公共成员,就要在该成员上加特性"JsonProperty"
[JsonProperty]
private int Height { get; set; }
自定义序列化属性名称
[JsonProperty(PropertyName = "CName")]
public string Name { get; set; }
动态决定属性是否序列化
根据不同场景选择要输出的属性,比如场景1需要序列化A、B、C属性,场景2序列化D、E属性
通过继承DefaultContractResolver类实现以上需求
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();
}
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));
指定key的显示格式
可以执行key的显示格式为驼峰命名,或自定义输出
//设置序列化时key为驼峰样式
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.Formatting = Formatting.Indented;//带缩进
string str = JsonConvert.SerializeObject(menus, settings);
Console.WriteLine(str);
循环引用处理
Newtonsoft.Json默认 已经处理过循环引用
//设置循环引用,及引用类型序列化的层数。
//注:目前在 EF core中目前不支持延迟加载,无所谓循环引用了
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
settings.MaxDepth = 10; //设置序列化的最大层数
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;//指定如何处理循环引用,None--不序列化,Error-抛出异常,Serialize--仍要序列化
枚举序列化成字符串
Newtonsoft提供了StringEnumConverter,它继承自JsonConverter,用于序列化时显示枚举的名称,而不是枚举值
public enum EType
{
[Description("type1")]
类型1 = 1,
[Description("type2")]
类型2 = 2
}
public class TestResponseModel
{
[JsonConverter(typeof(StringEnumConverter))]// DescriptionEnumJsonConverter
public EType Type { get; set; }
}
序列化后的结果:
{"Type":"类型1"}
如果想将输出内容改成枚举项上的[Description],可以将StringEnumConverter换成DescriptionEnumJsonConverter,代码如下
public class DescriptionEnumJsonConverter : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
try
{
if (objectType.IsEnum)
{
return this.GetValue(objectType, reader.Value, reader.Value.ToString());
}
return reader.Value;
}
catch (Exception)
{
throw new Exception(string.Format("不能将枚举{1}的值{0}转换为Json格式.", reader.Value, objectType));
}
}
/// <summary>
/// 判断是否为Bool类型
/// </summary>
/// <param name="objectType">类型</param>
/// <returns>为bool类型则可以进行转换</returns>
public override bool CanConvert(Type objectType)
{
return objectType.IsEnum;
}
public bool IsNullableType(Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
return type.BaseType != null
&& (type.BaseType.FullName == "System.ValueType"
&& type.GetGenericTypeDefinition() == typeof(Nullable<>)
)
;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
Type type = value.GetType();
if (type.IsEnum)
{
object description = GetEnumDescription(type, value);
if (description != null)
{
writer.WriteValue(description);
}
else
{
writer.WriteValue(value);
}
//serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
}
else
{
writer.WriteValue(value);
}
}
/// <summary>
/// 获取枚举描述
/// </summary>
/// <param name="type">枚举类型</param>
/// <param name="value">枚举hasecode</param>
/// <returns></returns>
private object GetEnumDescription(Type type, object value)
{
string name = System.Enum.GetName(type, value);
if (name == null)
{
return name;
}
FieldInfo field = type.GetField(name);
if (field == null)
{
return name;
}
var desc = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
if (desc != null)
{
return desc.Description;
}
return name;
}
private object GetValue(Type type, object value, string description)
{
object result = null;
var fieldInfo = type.GetFields(BindingFlags.Static | BindingFlags.Public).Where(t =>
{
var attr = t.GetCustomAttribute<DescriptionAttribute>();
if (attr != null)
{
return attr.Description.Equals(description, StringComparison.CurrentCultureIgnoreCase);
}
else {
return type.GetEnumName(t.GetValue(value)).Equals(description, StringComparison.CurrentCultureIgnoreCase);
}
return false;
})
.FirstOrDefault();
if (fieldInfo != null)
{
result = fieldInfo.GetValue(value);
}
return result ?? value;
}
}
序列化后的结果:
{"Type":"type1"}
自定义类型转换
参考:https://so.csdn.net/so/search?q=NewtonSoft.JSON官方手册中文版&t=blog&u=fanxiaojie119 (NewtonSoft.JSON官方手册中文版)