.net5 core webapi进阶之二:System.Text.Json的用法详解(下篇)JSON序列化和反序列化

本篇接着介绍 JSON 的序列化和反序列化。

一、要完成的功能如下:

1 . 序列化:实例化 Company 和 User 对象,并序列化成一个JSON字符串,对应终结点为 JsonDemo6( )

2 . 反序列化:读取配置文件appcom.json中的信息,并反序列化成 Company 和 User 对象,对应终结点为 JsonDemo7()

 

二、准备工作,给 Company.cs 和 User.cs 类加上相关属性

Company.cs 代码如下:

namespace webapidemo2
{
    public class Company
    {
        public string CompanyName{ get; set; }
        public string Website { get; set; }
        public string Address { get; set; }
        public User Boss { get; set; }
        public string[] PhoneNumber { get; set; }
        public List<User> Employees { get; set; }
    }
}

User.cs 代码如下:

namespace webapidemo2
{
    public class User
    { 
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Mobile { get; set; }  
    }
}

 

三、编码,2个终结点代码如下。

6 . 终结点: JsonDemo6(); 实现序列化。

        [Route("json6")]
        [HttpGet]
        public string Demo6()
        {
            //mock company和user实例数据;
            User boss = new User { UserId = 1001, UserName = "王五", Mobile = "13300047775" };
            List<User> employees = new List<User>();
            employees.Add(new User { UserId = 2113, UserName = "张三", Mobile = "13378465709" });
            employees.Add(new User { UserId = 3266, UserName = "李四", Mobile = "13378465709" });
            Company company = new Company
            {
                CompanyName = "top",
                Website = "www.xxxx.com",
                Address = "开曼群岛",
                PhoneNumber = new string[] { "010-93847485", "15890276458" },
                Boss = boss,
                Employees = employees
            };

            //调用 JsonSerializer 的 Serialize() 函数即可将实例序列化成JSON字符串
            string str = JsonSerializer.Serialize<Company>(company);
            
            return str; 
        }

打开 POSTMAN ,用 GET 方式访问网址:http://localhost:61946/api/jsondemo/json6 得到如下结果:

可以看到大部分内容序列化出来了,但中文字符被转义了,没有正常显示出来,字符内容也没有格式化,

所以我们在调用 JsonSerializer.Serialize( ) 方法的时候要传入 Options 对象来指定序列化时候的编码和格式,

修改后的方法如下(见红色代码部分):

        [Route("json6")]
        [HttpGet]
        public string Demo6()
        {
            //mock company和user实例数据;
            User boss = new User { UserId = 1001, UserName = "王五", Mobile = "13300047775" };
            List<User> employees = new List<User>();
            employees.Add(new User { UserId = 2113, UserName = "张三", Mobile = "13378465709" });
            employees.Add(new User { UserId = 3266, UserName = "李四", Mobile = "13378465709" });
            Company company = new Company
            {
                CompanyName = "top",
                Website = "www.xxxx.com",
                Address = "开曼群岛",
                PhoneNumber = new string[] { "010-93847485", "15890276458" },
                Boss = boss,
                Employees = employees
            };

            
            //指定Unicode的码位范围
            TextEncoderSettings setting = new TextEncoderSettings(
                                                UnicodeRanges.BasicLatin, //获取基本拉丁语 Unicode 块 (U+0021-U+007F)
                                                UnicodeRanges.CjkUnifiedIdeographs //获取 CJK 统一汉字 Unicode 块 (U+4E00-U+9FCC)
                                            );
            JsonSerializerOptions options = new JsonSerializerOptions
            {
                Encoder = JavaScriptEncoder.Create(setting), //设置字符编码
                WriteIndented = true //是否格式化
            };
            //调用 JsonSerializer 的 Serialize() 函数即可将实例序列化成JSON字符串
            string str = JsonSerializer.Serialize<Company>(company, options);
            
            return str; 
        }

编译项目后再次访问网址:http://localhost:61946/api/jsondemo/json6 得到如下期望的结果:

 

7 . 终结点: JsonDemo7(); 实现反序列化。

        [Route("json7")]
        [HttpGet]
        public string Demo7()
        { 
            //读取 appcom.json 文件中的内容反序列化到 Company.cs中
            string filePath = Path.GetFullPath("./appcom.json");  
            byte[] contents = System.IO.File.ReadAllBytes(filePath);

            ReadOnlySpan<byte> span = contents.AsSpan<byte>();

            //调用 JsonSerializer 的 Deserialize( ) 即可实现反序列化
            Company company = JsonSerializer.Deserialize<Company>(span);

            //输出 Company 实例中的内容看反序列化是否正确
            StringBuilder sb = new StringBuilder();
            sb.Append("CompanyName = "+ company.CompanyName+Environment.NewLine);
            sb.Append("Website = " + company.Website + Environment.NewLine);
            sb.Append("Address = " + company.Address + Environment.NewLine);
            sb.Append("Boss = {" + company.Boss.UserId + ":" + company.Boss.UserName + ":" + company.Boss.Mobile + "}" + Environment.NewLine);
            sb.Append("PhoneNumber = [ ");
            foreach (string s in company.PhoneNumber)
            {
                sb.Append(s + " ; ");
            }
            sb.Append("]" + Environment.NewLine);

            sb.Append("Employees = [" + Environment.NewLine);
            foreach (User user in company.Employees)
            {
                sb.Append("   Employee = {" + user.UserId + ":" + user.UserName + ":" + user.Mobile + "}" + Environment.NewLine);
            }
            sb.Append("]" + Environment.NewLine);

            return sb.ToString();
        }

 打开 POSTMAN ,用 GET 方式访问网址:http://localhost:61946/api/jsondemo/json7 得到如下结果:

可以看到 appcom.json 中属性名和 Company.cs 、User.cs中属性名相同(大小写也一致)的已经反序列化成功了,

appcom.json 中的小写的属性没有被反序列化, 要想忽略大小写,

在调用 JsonSerializer.Deserialize( ) 时要传入 Options 对象来指定反序列化时候的参数,

修改后的方法如下(见红色代码部分):

        [Route("json7")]
        [HttpGet]
        public string Demo7()
        { 
            //读取 appcom.json 文件中的内容反序列化到 Company.cs中
            string filePath = Path.GetFullPath("./appcom.json");  
            byte[] contents = System.IO.File.ReadAllBytes(filePath);

            ReadOnlySpan<byte> span = contents.AsSpan<byte>();

            JsonSerializerOptions options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true //忽略大小写
            };

            //调用 JsonSerializer 的 Deserialize( ) 即可实现反序列化
            Company company = JsonSerializer.Deserialize<Company>(span, options);

            //输出 Company 实例中的内容看反序列化是否正确
            StringBuilder sb = new StringBuilder();
            sb.Append("CompanyName = "+ company.CompanyName+Environment.NewLine);
            sb.Append("Website = " + company.Website + Environment.NewLine);
            sb.Append("Address = " + company.Address + Environment.NewLine);
            sb.Append("Boss = {" + company.Boss.UserId + ":" + company.Boss.UserName + ":" + company.Boss.Mobile + "}" + Environment.NewLine);
            sb.Append("PhoneNumber = [ ");
            foreach (string s in company.PhoneNumber)
            {
                sb.Append(s + " ; ");
            }
            sb.Append("]" + Environment.NewLine);

            sb.Append("Employees = [" + Environment.NewLine);
            foreach (User user in company.Employees)
            {
                sb.Append("   Employee = {" + user.UserId + ":" + user.UserName + ":" + user.Mobile + "}" + Environment.NewLine);
            }
            sb.Append("]" + Environment.NewLine);

            return sb.ToString();
        }

 编译项目后再次访问网址:http://localhost:61946/api/jsondemo/json6 得到如下结果:

可以看到所有属性和值都已经设置成功了。

 

posted @ 2021-02-23 12:12  屏风马  阅读(1571)  评论(1编辑  收藏  举报