从本篇开始写 .net5 core webapi 进阶系列,先从JSON这种数据格式开始,原因如下:
1 . 够简洁;
2 . 易于理解;
3 . 其格式和面向对象的语言天然匹配;
4 . 多语言(Javascript 、C# 、Java 等)支持;
毫无疑问,JSON是不同语言,不同系统之间进行数据交换的最好选择,没有之一,
如果XML代表着上一个10年,那么JSON将统治下一个10年,也许更久。。。
一 、System.Text.Json 的内部结构。
System.Text.Json.dll 程序集中有两个名称空间,分别是 System.Text.Json 和 System.Text.Json.Serialization,
用反编译工具打开System.Text.Json并只显示公有类型和成员,得到如下的类/结构:
System.Text.Json用于读写JSON,
System.Text.Json.Serialization用于JSON的序列化和反序列化。
二 、新建一个.net5 core webapi 项目演示System.Text.Json的用法。
项目名称为webapidemo2,按照惯例,
删除根目录下的 WeatherForecast.cs 文件和Controllers目录下的 WeatherForecastController.cs 文件,
新建一个API控制器文件 JsonDemoController.cs,如下:
在此文件中引用如下两个名称空间:
using System.Text.Json;
using System.Text.Json.Serialization;
在项目根目录下新建一个Models的文件夹,
然后添加一个 User.cs的类文件作为序列化和反序列化使用 ,如下:
User.cs代码如下:
namespace webapidemo2 { public class User { public string CompanyName { get; set; } public string Website { get; set; } public string Address { get; set; } public string[] PhoneNumber { get; set; } public int UserId { get; set; } public string UserName { get; set; } public string Mobile { get; set; } public DateTime Birthday { get; set; } } }
我们在 JsonDemoController.cs 这个控制器中编写6个终结点,分别完成如下6个功能:
1 . 终结点: JsonDemo1();作用:return 一个最简单的JSON字符串;
{"userid":123, "username":"jacky"}
2 . 终结点: JsonDemo2();作用:return 一个带字符串数组的JSON字符串;
{"userid":123, "username":"jacky", "mobile":["13244445555","18966667777"]}
3 . 终结点: JsonDemo3();作用:return 一个带对象数组的JSON字符串;
{"userid":123, "username":"jacky", "employees":[{"userid":834,"username":"simon"},{"userid":835,"username":"roger"}]}
4 . 终结点: JsonDemo4();作用:解析一个JSON文件,读取指定属性的值;
文件位于根目录下,名称叫 appcom.json,格式如下:
{ "CompanyName": "top", "Website": "www.xxxx.com", "Address": "开曼群岛", "Employees": [ { "userid": 2113, "username": "张三", "mobile": "13378465709" }, { "userid": 3266, "username": "李四", "mobile": "13378465709" } ], "PhoneNumber": ["010-93847485","15890276458"] }
5 . 终结点:JsonDemo5();作用:将User实例序列化成JSON对象;
6 . 终结点:JsonDemo6();作用:将JSON对象反序列化成User实例;
三 、编码,6个终结点的代码如下。
1 . 终结点: JsonDemo1();
[Route("json1")] [HttpGet] public string Demo1() { //{"userid":123, "username":"jacky"} //表示基于堆、使用字节数组存储数据的输出接收器,可向其中写入数据。 ArrayBufferWriter<byte> buffer = new ArrayBufferWriter<byte>(); //utf8编码的JSON写入器,可以将int,string,array等数据写入到JSON中 Utf8JsonWriter writer = new Utf8JsonWriter(buffer); writer.WriteStartObject(); //表示一个开头花括号 "{" //写入属性及其值,这两行语句可以换成 writer.WriteNumber("userid", 123); writer.WritePropertyName("userid"); writer.WriteNumberValue(123); writer.WriteString("username", "jacky"); writer.WriteEndObject(); //表示一个结尾花括号 "}" writer.Flush();//写入到buffer //ReadOnlySpan表示的存储区有更好的性能和内存开销 ReadOnlySpan<byte> span = buffer.WrittenSpan; string strJson = Encoding.UTF8.GetString(span); return strJson; }
打开POSTMAN ,用GET方式访问网址:http://localhost:61946/api/jsondemo/json1 得到如下结果:
2 . 终结点: JsonDemo2();
[Route("json2")] [HttpGet] public string Demo2() { //{"userid":123, "username":"jacky", "mobile":["13244445555","18966667777"]} ArrayBufferWriter<byte> buffer = new ArrayBufferWriter<byte>(); Utf8JsonWriter writer = new Utf8JsonWriter(buffer); writer.WriteStartObject(); writer.WriteNumber("userid", 123); writer.WriteString("username", "jacky"); //写入json数组开始,这两行语句可以换成 writer.WriteStartArray("mobile"); writer.WritePropertyName("mobile"); writer.WriteStartArray();//写入json数组结束,表示一个中括号[ writer.WriteStringValue("13244445555");//用对应的Value结尾的方法 writer.WriteStringValue("18966667777"); writer.WriteEndArray();//写入json数组结束,表示一个中括号] writer.WriteEndObject(); writer.Flush(); ReadOnlySpan<byte> span = buffer.WrittenSpan; string strJson = Encoding.UTF8.GetString(span); return strJson; }
打开POSTMAN ,用GET方式访问网址:http://localhost:61946/api/jsondemo/json2 得到如下结果:
3 . 终结点: JsonDemo3();
[Route("json3")] [HttpGet] public string Demo3() { //{"userid":123, "username":"jacky", "employees":[{"userid":834,"username":"simon"},{"userid":835,"username":"roger"}]} //mock一个泛型List<User>供下面使用 List<User> userList = new List<User>(); userList.Add(new User { UserId = 834, UserName = "simon" }); userList.Add(new User { UserId = 835, UserName = "roger" }); ArrayBufferWriter<byte> buffer = new ArrayBufferWriter<byte>(); Utf8JsonWriter writer = new Utf8JsonWriter(buffer); writer.WriteStartObject(); writer.WriteNumber("userid", 123); writer.WriteString("username", "jacky"); writer.WriteStartArray("employees"); foreach (User user in userList) { writer.WriteStartObject(); writer.WriteNumber("userid", user.UserId); writer.WriteString("username", user.UserName); writer.WriteEndObject(); } writer.WriteEndArray(); writer.WriteEndObject(); writer.Flush(); ReadOnlySpan<byte> span = buffer.WrittenSpan; string strJson = Encoding.UTF8.GetString(span); return strJson; }
打开POSTMAN ,用GET方式访问网址:http://localhost:61946/api/jsondemo/json3 得到如下结果:
(待续...)