Json格式做为主流的报文传输格式,成熟的类库也不少,但是C#用的比较多的就是Newtonsoft.Json,下文将介绍基于Newtonsoft.Json库对json格式化、json解析,基础用法与高级用法,官方网站
基础用法
1、序列化/反序列化对象
class Program
{
static void Main(string[] args)
{
var tmp = new JsonModel()
{
Departments = new List<Department>()
{
new Department(){ Id=1, Name="001"},
new Department(){ Id=1, Name="002"}
},
Name = "张三",
Phone = new List<string>() { "110", "112" },
Sex = 1
};
//序列化对象
var json = JsonConvert.SerializeObject(tmp, Formatting.Indented/*Indented格式化json字符串,none为压缩字符串*/);
//反序列化对象
JsonModel model = JsonConvert.DeserializeObject<JsonModel>(json);
Console.ReadKey();
}
public class JsonModel
{
[JsonProperty("userName")]/*json节点名,若属性名和节点名一致则忽略*/
public string Name { get; set; }
public int Sex { get; set; }
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
public List<string> Phone { get; set; }
[JsonProperty("departments")]
public List<Department> Departments { get; set; }
[JsonIgnore]/*打上此标记,则序列化/反序列化时忽略此属性*/
public string TestFiled { get; set; }
}
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
}
public class User
{
public int Age { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
[JsonIgnore]
public int Id { get; set; }
}
}
2、序列化DataTable
static void Main(string[] args)
{
//添加datatable测试数据
DataTable _dataTable = new DataTable();
_dataTable.Columns.Add(new DataColumn("userName", typeof(string)));
_dataTable.Columns.Add(new DataColumn("userId", typeof(int)));
_dataTable.Columns.Add(new DataColumn("birthday", typeof(string)));
_dataTable.Columns.Add(new DataColumn("sex", typeof(string)));
_dataTable.Rows.Add(new string[] {
"张三",
"100",
"2020-08-01",
"女"
});
_dataTable.Rows.Add(new string[] {
"李四",
"100",
"2020-08-01",
"男"
});
var json = JsonConvert.SerializeObject(_dataTable, Formatting.Indented);
Console.WriteLine(json);
Console.ReadKey();
}
进阶用法
1、忽略某些属性
- 实体中有些属性不需要序列化返回,在不需要返回的属性上加上[JsonIgnore]说明即可忽略该属性。
- 如下代码,不需要Id属性:
public class User
{
public int Age { get; set;}
public string Name { get;set; }
public string Sex { get;set; }
[JsonIgnore]
public int Id { get; set; }
}
通过上面的例子可以看到,忽略某些属性的序列化/反序列化需求很简单。
2、默认值的处理
- 序列化时想忽略默认值属性可以通过DefaultValueHandling来设置,另外通过JsonSerializerSettings设置属性是对序列化过程中所有属性生效的,想单独对某一个属性生效可以使用JsonProperty,下面将分别展示两个方式。
- DefaultValueHandling.Ignore 序列化和反序列化时,忽略默认值
- DefaultValueHandling.Include 序列化和反序列化时,包含默认值
- 忽略单个属性默认值Age
public class User
{
[JsonProperty(DefaultValueHandling= DefaultValueHandling.Ignore)]
[DefaultValue(10)]
public int Age { get; set;}
public string Name { get;set; }
public string Sex { get;set; }
[JsonIgnore]
public int Id { get; set; }
}
运行结果如下,默认值10已被忽略
补充:全局忽略属性默认值
JsonSerializerSettings setting = newJsonSerializerSettings();
setting.NullValueHandling =NullValueHandling.Ignore;
var resJson =JsonConvert.SerializeObject(new User()
{
Id = 100,
Name = "张三",
Sex = "男"
}, setting);
3、属性空值的处理
- 序列化时需要忽略值为NULL的属性,可以通过NullValueHandling来设置,另外通过JsonSerializerSettings设置属性是对序列化过程中所有属性生效的,想单独对某一个属性生效可以使用JsonProperty,下面将分别展示两个方式。
- 忽略单个值为NULL的属性,本次忽略Name属性,若Name属性为NULl,则忽略
public class User
{
public int Age { get; set;}
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Name { get;set; }
public string Sex { get;set; }
public int Id { get; set; }
}
运行结果如下,Name字段已被忽略
补充:全局忽略值为NULL的属性
JsonSerializerSettings setting = newJsonSerializerSettings();
setting.NullValueHandling =NullValueHandling.Ignore;
var resJson = JsonConvert.SerializeObject(newUser()
{
Id = 100,
Sex = "男"
}, setting);
4、支持非公共成员
- 序列化时默认都是只处理公共成员,如果需要处理非公共成员,就要在该成员上加特性[JsonProperty]
[JsonProperty]
private int Name{ get; set; }
5、支持压缩/格式化
- 序列化默认都是内容压缩,以减小文本容量让其在网络中传输更快;但是如果需要缩进换号的文本格式,可利用JsonSerializerSettings中的Formatting属性进行设置。
- Formatting.Indented 序列化结果缩进换号
- Formatting.None 序列化结果压缩,去除缩进与换行
JsonSerializerSettings setting = new JsonSerializerSettings();
setting.Formatting = Formatting.Indented;
var resJson = JsonConvert.SerializeObject(new User()
{
Id = 100,
Name = "张三",
Sex = "男"
}, setting);
6、日期特殊处理
- 对于Dateime类型日期字段,系统自带的会格式化成ISO日期标准;但是实际使用过程中大多数使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss一类的格式,可以采用下面方案解决此类问题。
- Newtonsoft.Json提供了IsoDateTimeConverter日期转换这个类,可以通过JsnConverter实现相应的日期转换
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime Birthday { get; set; }
补充:若IsoDateTimeConverter日期格式不是我们想要的,我们可以继承DateTimeConverterBase类实现自己的日期格式
public class CustDateTimeConverter : DateTimeConverterBase
{
private static IsoDateTimeConverter _converter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, existingValue, serializer);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
_converter.WriteJson(writer, value, serializer);
}
}
7、JSON字段别名
- 实体中定义的属性名和JSON节点名称可能不一致,但是又不能更改实体定义,这个时候可以自定义序列化字段名称。
[JsonProperty(PropertyName = "userName")]
public string Name { get; set; }
8、枚举值序列化
- 默认情况下对于实体里面的枚举类型系统是格式化成改枚举对应的值,若要格式化成枚举对应的字符,在对于的属性上方加上“
- [JsonConverter(typeof(StringEnumConverter))]”即可。
public class User
{
public int Age { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public int Id { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public UserType UserType { get; set; }
}
public enum UserType
{
系统用户 = 0,
前台用户 = 1
}