首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

无法使用System.Text.Json反序列化DateTime、Guid或枚举

问题概述

在使用 System.Text.Json 进行 JSON 反序列化时,可能会遇到无法正确处理 DateTimeGuid 或枚举类型的情况。这些问题通常是由于默认的反序列化行为不满足特定需求导致的。

基础概念

  • 反序列化:将 JSON 数据转换为 .NET 对象的过程。
  • DateTime:表示日期和时间的结构体。
  • Guid:表示全局唯一标识符的结构体。
  • 枚举:一种用户定义的数据类型,包含一组命名的常量。

相关优势

  • System.Text.Json 是 .NET Core 和 .NET 5/6/7+ 中推荐的 JSON 序列化和反序列化库,具有高性能和低内存占用。
  • 支持自定义序列化和反序列化逻辑,可以灵活处理复杂的数据类型。

类型与应用场景

  • DateTime:用于处理日期和时间数据,常见于日志记录、日程管理、数据分析等场景。
  • Guid:用于生成全局唯一标识符,常见于数据库主键、分布式系统中的唯一标识等场景。
  • 枚举:用于定义一组固定的常量,常见于状态码、配置选项等场景。

问题原因及解决方法

1. DateTime 反序列化问题

问题原因:默认情况下,System.Text.Json 可能无法正确解析某些日期时间格式。

解决方法

代码语言:txt
复制
using System.Text.Json;
using System.Text.Json.Serialization;

public class MyClass
{
    [JsonConverter(typeof(JsonStringConverter<DateTime>))]
    public DateTime MyDateTime { get; set; }
}

public class JsonStringConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            return JsonSerializer.Deserialize<T>(reader.GetString(), options);
        }
        throw new JsonException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(JsonSerializer.Serialize(value, options));
    }
}

2. Guid 反序列化问题

问题原因:默认情况下,System.Text.Json 可能无法正确解析某些 Guid 格式。

解决方法

代码语言:txt
复制
using System.Text.Json;
using System.Text.Json.Serialization;

public class MyClass
{
    [JsonConverter(typeof(JsonStringConverter<Guid>))]
    public Guid MyGuid { get; set; }
}

public class JsonStringConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            return JsonSerializer.Deserialize<T>(reader.GetString(), options);
        }
        throw new JsonException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(JsonSerializer.Serialize(value, options));
    }
}

3. 枚举反序列化问题

问题原因:默认情况下,System.Text.Json 可能无法正确解析枚举值。

解决方法

代码语言:txt
复制
using System.Text.Json;
using System.Text.Json.Serialization;

public enum MyEnum
{
    Value1,
    Value2
}

public class MyClass
{
    [JsonConverter(typeof(JsonStringConverter<MyEnum>))]
    public MyEnum MyEnumValue { get; set; }
}

public class JsonStringConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            return JsonSerializer.Deserialize<T>(reader.GetString(), options);
        }
        throw new JsonException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(JsonSerializer.Serialize(value, options));
    }
}

参考链接

通过上述方法,可以解决 System.Text.Json 在反序列化 DateTimeGuid 和枚举类型时遇到的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

.NET WebAPI 自定义 NullableConverter 解决可为空类型字段入参“”空字符触发转换异常问题

来标记一个字段是否允许为空,但是使用过程中遇到了如下一个问题,比如创建部门接口 我们定义入参模型如下: public class DtoDepartment { /// ...using System.Text.Json; using System.Text.Json.Serialization; namespace Common.JsonConverter { public...Value, options); } } } 上面我们只是用 Guid? 举了一个例子,实际情况下 DateTime? DateTimeOffset? long? int?...这样前端在调用接口时配到这类型的字段,传 "" 和 null 我们后端就都可以接收了,收到之后字段的值都是 null 我这里项目采用的是微软的 System.Text.Json 处理的 Json 序列化...,注册配置 NullableConverter 代码如下: #region 注册 Json 序列化配置 builder.Services.AddControllers().AddJsonOptions(

76940

.NETCore3.1中的Json互操作最全解读-收藏级

JsonSerializerOptions 与上面的 JsonSerializer 配合使用,提供自定义的个性化互操作选项,包括命名、枚举转换、字符转义、注释规则、自定义转换器等等操作选项。...,为了进一步缩小内存使用率,Json团队用心良苦的将枚举值声明为:byte 类型(够抠) public enum JsonValueKind : byte { Undefined = 0,...序列化和反序列化 基本知识已经介绍完成,下面我们进入 System.Text.Json 的内部世界一探究竟。...在反序列化的时候,允许 JSON 文本包含注释 默认情况下,System.Text.JSON 不支持源JSON 文本包含注释,比如下面的代码,当你不使用 ReadCommentHandling = JsonCommentHandling.Skip...结束语 本文全面的介绍了 System.Text.Json 在各种场景下的用法,并比较和 Newtonsoft.Json 使用上的不同,也通过实例演示了具体的使用方法,进一步深入讲解了 System.Text.Json

2.7K21
  • .NET性能系列文章一:.NET7的性能改进

    这大大改善了一些 LINQ 方法性能,你可以在Listint[]以及其他数字集合上调用。现在 LINQ 方法也能直接访问底层数组,而不是使用枚举器访问。...它们被用来识别数字枚举中的最低值最高值。新的实现特别要求有一个先前枚举的集合作为源,因此我们必须在这个基准测试中创建一个数组。...我们无法看到这两种方法之间的性能影响。然而,我们可以看到的是在堆内存分配方面有很大的改进,这将显著减少垃圾收集,从而节省一些 GC 时间。...(System.Text.Json) 来自System.Text.Json命名空间的JsonSerializer得到了一个小小的升级,一些使用了反射的自定义处理程序会在幕后为你缓存,即使你初始化一个JsonSerialzierOptions...由于有大量的 API 使用Guid作为实体的标识符,这肯定会积极的产生影响。 2. BigInt 解析 一个很大的改进发生在将巨大的数字从字符串解析为BigInteger类型。

    84520

    .NET性能系列文章一:.NET7的性能改进

    这大大改善了一些 LINQ 方法性能,你可以在Listint[]以及其他数字集合上调用。现在 LINQ 方法也能直接访问底层数组,而不是使用枚举器访问。...它们被用来识别数字枚举中的最低值最高值。新的实现特别要求有一个先前枚举的集合作为源,因此我们必须在这个基准测试中创建一个数组。...我们无法看到这两种方法之间的性能影响。然而,我们可以看到的是在堆内存分配方面有很大的改进,这将显著减少垃圾收集,从而节省一些 GC 时间。...(System.Text.Json) 来自System.Text.Json命名空间的JsonSerializer得到了一个小小的升级,一些使用了反射的自定义处理程序会在幕后为你缓存,即使你初始化一个JsonSerialzierOptions...由于有大量的 API 使用Guid作为实体的标识符,这肯定会积极的产生影响。 2. BigInt 解析 一个很大的改进发生在将巨大的数字从字符串解析为BigInteger类型。

    68120

    ASP.NET Core Web API设置响应输出的Json数据格式的两种方式

    前言 在ASP.NET Core Web API中设置响应输出Json数据格式有两种方式,可以通过添加System.Text.JsonNewtonsoft.JsonJSON序列化和反序列化库在应用程序中全局设置接口响应的...Json数据格式,本文示例使用的是新的Minimal API模式。...JSON序列化和反序列化System.Text.Json System.Text.Json是 .NET Core 3.0 及以上版本中内置的 JSON 序列化和反序列化库。...设置Json统一格式需求 修改属性名称的序列化方式,在.Net Core中默认使用小驼峰序列化Json属性参数,前端想要使用与后端模型本身命名格式输出(如:UserName)。...未配置之前的API输出Json数据 UserInfoModel     public class UserInfoModel     {         public DateTime DateTime

    83010

    如何使用 System.Text.Json 序列化 DateTimeOffset 为 Unix 时间戳

    在 .NET 中,日期和时间通常使用 DateTime DateTimeOffset 来表示。这两种数据类型都可以表示日期和时间,但它们之间有一些明显的区别。...NET 提供了多种方法来实现 JSON 序列化,其中 System.Text.Json 库是 .NET Core 3.0 以后推出的新型 JSON 序列化器,它比早期的 DataContractJsonSerializer...在本文中,我们将探讨如何在 System.Text.Json 中将 DateTimeOffset 序列化为时间戳。...代码示例 下面是一个简单的 .NET Core 控制台应用,它演示了如何使用 System.Text.Json 库将 DateTimeOffset 序列化为时间戳。...总结 本文介绍了如何使用 System.Text.Json 库将 DateTimeOffset 序列化为时间戳。

    33820

    .NET性能系列文章二:Newtonsoft.Json vs System.Text.Json

    第一,单个大数据集的序列化和反序列化。 第二是许多小数据集的序列化和反序列化。 一个真实的场景也需要真实的数据。对于测试数据集,我决定使用 NuGet 包Bogus[5]。...,目前是(2022 年 10 月): Newtonsoft.Json — 13.0.1 and System.Text.Json — 7.0.0-rc.2[6] 序列化测试 序列化大对象 为了测试一个大对象的序列化...为了实现这个用例,我们使用之前建立的List,并简单地循环通过它,同时单独序列化每个用户。...在下面的基准中,我们将再次使用 Bogus,创建一组用户,但这次我们要把它们序列化为一个大的字符串,用于大数据对象,并把许多小数据对象序列化为List。...我甚至认为,可以推断出结果,目前使用System.Text.Json比Newtonsoft.Json更快。 请记住,这些结果只对最新的.NET 7 有效。

    1.5K30

    使用 C# 9 的records作为强类型ID - JSON序列化

    System.Text.Json 在最新版本的ASP.NET Core(从3.0)中,默认的JSON序列化程序是System.Text.Json,因此让我首先介绍这种。...options.JsonSerializerOptions.Converters.Add( new StronglyTypedIdJsonConverterFactory()); }); Newtonsoft.Json 如果您的项目使用的是...Newtonsoft.Json进行JSON序列化,那就很简单了。...: "Apple", "unitPrice": 0.8 } 几乎是正确的……除了id值不应序列化为字符串,而应序列化为数字,如果id值是GUID字符串而不是int,那就很好,则需要编写一个自定义转换器...它和 System.Text.Json 的转换器非常相似,不同之处在于Newtonsoft.Json没有转换器工厂(ConvertFactory)的概念,相反,我们将编写一个非泛型转换器: public

    1.5K10

    官方盘点 .NET 7 新功能

    无法从操作系统机器的 BIOS 中获取 L3 缓存大小,我们通过更改启发式方法以返回近似大小。现在我们可以更好地估计每个 L3 缓存大小的内核数。...; ▌System.Text.Json 合约定制 System.Text.Json 通过为该类型构造 JSON 契约来确定给定 .NET 类型如何被序列化和反序列化。...要了解有关源生成器的更多信息,请参阅如何在 System.Text.Json使用源生成。...类型层次结构 System.Text.Json 现在支持用户定义类型层次结构的多态序列化和反序列化。...这可以以与使用标志样式枚举相同的方式使用。此类参数的常见示例可能是: 在 Web 模板上选择多种形式的身份验证。 在 MAUI 模板中一次选择多个目标平台(iOS、Android、Web)。

    1.6K10

    Unity3D网络通讯(一)--Asp.Net Core WebApi创建发布注意事项

    03 Json大小写的问题 其实按照上面两步,基本我们的IIS的网站也搭建成,可以正常使用了,不过我在用Unity3D调用的时候发现Json反序列化时对应的类值都解析不出来,搜索查了一下原因是Unity3D...默用的Json序列化组件是JsonUnity,它对大小写比较敏感,而NetCore3.1之后默认的序列化组件改为了System.Text.Json序列化的默认行为有变。...默认的System.Text.Json与Newtonsoft.Json的序列化对比,可以看到默认的System.Text.Json中把我们类属性全都转为小写了,而用了Newtonsoft.Json后还是按类属性的原值输出的...改为NewtonsoftJson后,Unity3D使用JsonUnity也可以正常反序列化了。 Controller代码 ?...return Enumerable.Range(1,1).Select(idx => new WeatherForecast { Date = DateTime.Now.AddDays

    1.4K10

    .NET 6+ 中的源生成器诊断

    如果你遇到其中一个生成警告错误,请按照为参考部分列出的诊断 ID 提供的具体指导进行操作。 还可以使用特定的 SYSLIB1XXX 诊断 ID 值来取消警告。 有关详细信息,请参阅取消警告。...(例如不成对的大括号) SYSLIB1023 不支持生成六个以上的参数 SYSLIB1030 System.Text.Json 源生成器未生成类型的序列化元数据 SYSLIB1031 System.Text.Json...System.Text.Json 源生成器遇到无效的 [JsonExtensionData] 注释 SYSLIB1037 System.Text.Json 源生成器遇到具有仅初始化属性的类型,这些属性不支持反序列化...SYSLIB1038 System.Text.Json 源生成器遇到使用 [JsonInclude] 注释的属性,该属性具有不可访问的访问器 禁止显示警告 建议尽量使用解决方法之一。...但是,如果无法更改代码,可以通过 #pragma 指令 项目设置来禁止显示警告。 如果 SYSLIB1XXX 源生成器诊断未显示为错误,则可以在代码项目文件中禁止警告。

    57120

    菜菜从零学习WCF十(序列化)

    DtaContractSerializer有许多构造函数重载,但必须使用type参数听歌至少一个根类型   为某个根类型创建的序列化程序不能用于序列化序列化)其他类型,除非该类型是从根类型派生的。...2.指定已知类型   如果在进行序列化的类型中涉及多态性并且尚未使用KnowTypeAttribute属性一些其他机制进行处理,则必须使用KnownTypes参数将可能的已知类型的列表传递给序列化程序的构造函数...枚举类型。枚举(包括标志枚举)是可序列化的。...或者可以使用DataContractAttribute属性对枚举类型进行标记,在这种情况下,必须使用EnumMemberAttribute属性对每个成员进行标记。   ...这些类型有DateTime、DateTimeOffset、TieSpan、Guid、Uri、XmlQualifiedName和Byte数   使用SerializableAttribute属性标记的类型

    1.1K30

    Newtonsoft.Json

    开发过程中通常会使用Json进行数据交互,C#语言中会使用到Newtonsoft.Json.dll 这个类库,这个类库是开源类库,虽然类库非微软官方,但是被广泛使用; 源码地址:https://github.com...String Byte[] string Type String(类型名称) Guid string typeConverter string C#对象、集合、DataTable与Json内容互转示例...image.png 【NullValueHandling:这是每个枚举值,Ignore忽略空值,Include包含空值】 方式2:通过上面的示例,我们可以发现,可以对单个属性进行设置,如果一个实体类有20...JsonSerializerSettings竟然没有构造函数,一点都不OOP string json = JsonConvert.SerializeObject(p, setting); 转换结果如下图: image.png 序列化枚举值的处理...方法来有条件地序列化属性,要有条件地序列化属性,需要在对象类中增加一个与该属性同名的布尔值的方法,然后使用ShouldSerialize作为方法名称的前缀,比如你要设置属性字段Name根据条件来动态决定是否序列化

    2.4K80

    【C# XML 序列化】开篇

    (2)索引器、私有字段只读属性(只读集合属性除外)不能被序列化;若要序列化对象的所有公共和私有字段和属性,请使用 DataContractSerializer 而不要使用 XML 序列化。...; (4)方法不能被序列化(虽然是废话,但是还是列举出来); (5)枚举变量可序列化为字符串,无需用[XmlInclude] (6)导出非基本类型对象,都必须用[XmlInclude]事先声明。...(针对值类型有效) (8)某些类就是无法XML序列化的(即使使用了[XmlInclude]) 比如:IDictionary(如HashTable);父类对象赋予子类对象值的情况;对象间循环引用; (9)...对于无法XML序列化的对象,可考虑: 1、使用自定义xml序列化(实现IXmlSerializable接口); 2、实现IDictionary的类,可考虑: (1)用其它集合类替代;...这是因为 DataContratSerializer 显式显示了哪些字段属性被序列化为 XML。

    46331

    asp.net core 关于自增长ID数据保护(IDOR漏洞)

    制造这个问题的原因不就是因为ID是数字自增长吗,我只要让主键无规律不就行了,比如时间戳加随机数,再比如GUID。猜?你慢慢猜去吧。但是这里面涉及到一个小问题,性能和存储空间的问题。...(自增长主键和GUID查询性能和占用空间比较) 正如三解决方案,我只要让抛到前台的主键是无规律的并且不可轻松枚举出来好像就可以了.此处是对称加密(百度“对称加密有哪些”)。...我用的是微软自带的序列化组件,至于Newtonsoft.Json只是API不同罢了,逻辑一样。...= 0) { var nowDate = DateTime.Now; str = _protector.Protect(value.ToString...(str); } } 用法: [JsonConverter(typeof(ProtectionConverter))] public long ID { get; set; } 复制代码 使用序列化组件特性方式来解决

    1K20
    领券