.Net Core Json序列化和反序列化以及自定义JsonConverter<T>来转化特殊日期时间格式

System.Text.Json 命名空间提供用于序列化和反序列化 JavaScript 对象表示法 (JSON) 的功能。
System.Text.Json 命名空间包含所有入口点和主要类型。 System.Text.Json.Serialization 命名空间包含用于高级方案的特性和 API,以及特定于序列化和反序列化的自定义。

.Net Core中内置了对Json的转化与解析,默认对转化出的字段(属性)区分大小写。可将PropertyNameCaseInsensitive = true

设置为不区分大小写。

新建.Net Core 3.1 控制台应用程序JsonDemo,测试代码如下:

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * System.Text.Json 命名空间提供用于序列化和反序列化 JavaScript 对象表示法 (JSON) 的功能。
             * System.Text.Json 命名空间包含所有入口点和主要类型。 System.Text.Json.Serialization 命名空间包含用于高级方案的特性和 API,以及特定于序列化和反序列化的自定义
            */
            Console.WriteLine("测试将类序列号为json字符串....");
            TestClass test = new TestClass()
            {
                Id = 25,
                MyName = "张三",
                Summary = "abcd",
                CurrentTime = DateTime.Now
            };
            string jsonResult = JsonSerializer.Serialize(test,
                new JsonSerializerOptions()
                {
                    //中日韩统一表意文字(CJK Unified Ideographs) CJK (Chinese Japanese Korean) 汉字。CJK 是《GB2312-80》、《BIG5》等字符集的超集
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.BasicLatin, System.Text.Unicode.UnicodeRanges.CjkUnifiedIdeographs),
                    WriteIndented = true //打印空格字符对齐
                });
            Console.WriteLine(jsonResult);
            Console.WriteLine("测试将json字符串转换为指定的对象...");
            string jsonString = @"[{""PlayerId"":15,""PlayerName"":""柷敔"",""Address"":""天晴之海""},{""PlayerId"":22,""playerName"":""越今朝"",""WEAPON"":""双剑""}]";
            try
            {                
                List<Role> list1 = JsonSerializer.Deserialize<List<Role>>(jsonString,
                    new JsonSerializerOptions()
                    {
                        //忽略大小写,如果不设置,默认区分大小写
                        PropertyNameCaseInsensitive = true
                    });
                list1.ForEach(role => Console.WriteLine($"编号:{role.PlayerId},姓名:{role.PlayerName},地址:{role.Address},武器:{role.Weapon}"));
                jsonString = @"[{""PlayerId"":15,""PlayerName"":""柷敔"",""Address"":""天晴之海""},{""PlayerId"":""22"",""playerName"":""越今朝"",""Weapon"":""双剑""}]";
                Role[] list2 = JsonSerializer.Deserialize<Role[]>(jsonString,
                    new JsonSerializerOptions()
                    {
                        //忽略大小写
                        PropertyNameCaseInsensitive = true
                    });
                foreach (Role role in list2)
                {
                    Console.WriteLine($"编号:{role.PlayerId},姓名:{role.PlayerName},地址:{role.Address},武器:{role.Weapon}");
                }
            }
            catch (Exception ex) 
            {
                Console.WriteLine("json转换时出现异常:" + ex.Message);
            }
            Console.WriteLine("测试特殊日期时间格式的json转换...");
            TestSpecialDateTimeConverter();
            Console.ReadLine();
        }

        /// <summary>
        /// 对于特殊日期时间格式的json转换
        /// 参考文档:https://docs.microsoft.com/zh-cn/dotnet/standard/datetime/system-text-json-support
        /// </summary>
        static void TestSpecialDateTimeConverter() 
        {
            // Parsing non-compliant format as DateTime fails by default.
            try
            {
                //使用默认的转换器 转化日期时间 失败
                DateTime dt = JsonSerializer.Deserialize<DateTime>(@"""Thu, 25 Jul 2019 13:36:07 GMT""");
                Console.WriteLine(dt);
            }
            catch (JsonException e)
            {
                Console.WriteLine(e.Message);
            }

            // Using converters gives you control over the serializers parsing and formatting.
            //使用自定义转化器;
            JsonSerializerOptions options = new JsonSerializerOptions();
            options.Converters.Add(new DateTimeConverterForCustomStandardFormatR());

            string testDateTimeStr = "Thu, 25 Jul 2019 13:36:07 GMT";
            string testDateTimeJson = @"""" + testDateTimeStr + @"""";

            DateTime resultDateTime = JsonSerializer.Deserialize<DateTime>(testDateTimeJson, options);
            Console.WriteLine(resultDateTime);

            Console.WriteLine(JsonSerializer.Serialize(DateTime.Parse(testDateTimeStr), options));
        }
    }

    /*
     * 使用 Utf8Parser 和 Utf8Formatter
如果输入 DateTime 或 DateTimeOffset 文本表示形式符合 "R"、"l"、"O"、"G" 标准日期和时间格式字符串中的一个或 "G"标准日期和时间格式字符串,或者需要根据这些格式中的一种进行写入,则可以在转换器逻辑中使用快速的基于 utf-8 的分析和格式设置方法。 
这比使用 DateTime(Offset).Parse 和 DateTime(Offset).ToString快得多。
此示例演示一个自定义转换器,该转换器根据"R" 标准格式对 DateTime 值进行序列化和反序列化
    */
    /// <summary>
    /// 自定义转换器。需实现抽象类JsonConverter&lt;T&gt;的抽象方法Read和Write
    /// </summary>
    public class DateTimeConverterForCustomStandardFormatR : JsonConverter<DateTime>
    {
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            System.Diagnostics.Debug.Assert(typeToConvert == typeof(DateTime));
            if (System.Buffers.Text.Utf8Parser.TryParse(reader.ValueSpan, out DateTime value, out _, 'R'))
            {
                return value;
            }

            throw new FormatException();
        }

        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            // The "R" standard format will always be 29 bytes.
            Span<byte> utf8Date = new byte[29];

            bool result = System.Buffers.Text.Utf8Formatter.TryFormat(value, utf8Date, out _, new System.Buffers.StandardFormat('R'));
            System.Diagnostics.Debug.Assert(result);

            writer.WriteStringValue(utf8Date);
        }
    }

    /// <summary>
    /// 角色
    /// </summary>
    class Role 
    {
        /// <summary>
        /// 编号
        /// </summary>
        public int PlayerId { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string PlayerName { get; set; }
        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }
        /// <summary>
        /// 地址
        /// </summary>
        public string Weapon { get; set; }
    }

    /// <summary>
    /// 测试类
    /// </summary>
    class TestClass
    {
        public int Id { get; set; }
        public string MyName { get; set; }
        /// <summary>
        /// 可以被忽略的属性
        /// </summary>
        [JsonIgnore]
        public string Summary { get; set; }
        /// <summary>
        /// 当前时间
        /// </summary>
        public DateTime CurrentTime { get; set; }
    }
}
程序运行如图:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
.NET Core 中,可以使用 System.Text.Json 来进行对象的 JSON 序列化反序列化。与 Newtonsoft.Json 相比,System.Text.Json 具有更高的性能和更低的内存消耗。 以下是使用 System.Text.Json 进行对象的 JSON 序列化反序列化的示例代码: 1. 对象的 JSON 序列化 ``` using System; using System.Text.Json; public class Person { public string Name { get; set; } public int Age { get; set; } } Person person = new Person { Name = "Alice", Age = 30 }; string json = JsonSerializer.Serialize(person); Console.WriteLine(json); // 输出:{"Name":"Alice","Age":30} ``` 2. JSON 字符串的反序列化为对象 ``` string json = "{\"Name\":\"Alice\",\"Age\":30}"; Person person = JsonSerializer.Deserialize<Person>(json); Console.WriteLine(person.Name); // 输出:Alice Console.WriteLine(person.Age); // 输出:30 ``` 在以上示例中,通过 JsonSerializer.Serialize 方法将对象序列化JSON 字符串,通过 JsonSerializer.Deserialize 方法将 JSON 字符串反序列化为对象。 需要注意的是,System.Text.Json 默认情况下不支持将属性名的驼峰命名方式转换为下划线命名方式。如果需要支持该功能,可以在序列化反序列化时设置 JsonSerializerOptions.PropertyNamingPolicy 属性,例如: ``` JsonSerializerOptions options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; string json = JsonSerializer.Serialize(person, options); Person person = JsonSerializer.Deserialize<Person>(json, options); ``` 以上示例中,将 JsonSerializerOptions.PropertyNamingPolicy 属性设置为 JsonNamingPolicy.CamelCase,表示属性名使用驼峰命名方式。如果需要使用下划线命名方式,可以将该属性设置为 JsonNamingPolicy.SnakeCase

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值