导读:本期聚焦于林则安创作的《C#如何实现JSON反序列化?常用方法与实战示例详解》,敬请观看详情。把接口返回的JSON字符串还原成C#对象是日常联调中最容易出错的环节。直接手写字符串截取不仅难维护,遇到嵌套结构更是寸步难行。实际上.NET平台提供了多套成熟方案:原生System.Text.Json强调性能与安全,第三方Newtonsoft.Json以灵活著称。二者在命名映射、空值处理、自定义转换上的差异,直接决定了代码健壮性。本文从底层解析逻辑切入,对比不同库的适用边界,并给出可运行的代码示例,帮助你在控制台、Web接口等场景中正确还原数据模型。

在C#开发中,服务端或第三方接口通常以JSON文本形式传递数据,客户端必须将这些文本还原为内存中的强类型对象,这一过程就是JSON反序列化。与序列化关注如何把对象转为字符串不同,反序列化要解决类型匹配、字段映射、格式容错等问题。如果处理方式不当,轻则拿到空对象,重则抛出运行时异常导致程序中断。

C#如何实现JSON反序列化?常用方法与实战示例详解

使用System.Text.Json完成基础反序列化

从.NET Core 3.0开始,微软在基础类库中内置了System.Text.Json命名空间,它不依赖外部包,主打高性能和低内存分配。其核心类型是JsonSerializer,通过静态方法Deserialize可以把字符串或流转换为指定泛型类型的实例。该库默认采用严格匹配策略,即JSON属性名必须与C#类属性名完全一致,且区分大小写。

假设我们有一个表示用户的类,包含编号和姓名两个字段。当接口返回{"id":1,"name":"张三"}时,直接调用反序列化即可获得对象。如果JSON里写的是UserId而类里是id,默认配置下会无法赋值。此时可以通过在属性上标记JsonPropertyName特性来建立映射关系,这样即使前后端命名风格不同也能正确绑定。

下面展示一个最小可运行示例,演示如何读取JSON并转为实体。注意代码中使用了using System.Text.Json;引入命名空间,并且通过JsonSerializerOptions关闭了大小写敏感,以提升容错能力。

using System;
using System.Text.Json;

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        string json = "{"id":1,"name":"张三"}";
        var options = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        };
        User user = JsonSerializer.Deserialize<User>(json, options);
        Console.WriteLine($"编号:{user.Id},姓名:{user.Name}");
    }
}

这种原生方式的优势在于无需额外安装组件,适合对体积和启动速度敏感的应用。但它的灵活性相对较弱,例如处理动态字段、多态对象时需要编写自定义转换器,学习曲线比第三方库略陡。在简单DTO映射场景中,它往往是首选方案。

借助Newtonsoft.Json应对复杂结构

Newtonsoft.Json(常称Json.NET)是早期.NET生态中使用最广泛的JSON框架,其最大特点是配置灵活、扩展性强。它通过JsonConvert.DeserializeObject方法提供反序列化入口,并支持大量特性如JsonIgnoreJsonProperty来控制字段行为。对于历史项目或需要兼容多种格式的老接口,它依然是稳妥选择。

当JSON中存在可选字段、不同命名风格或需要忽略空值时,Newtonsoft只需在类定义或调用处设置即可。例如接口可能返回user_name这种下划线风格,我们可以在属性上用[JsonProperty("user_name")]标注,库会自动完成映射。此外它内置了对JObject的支持,允许先解析为动态结构再按需取值,避免定义完整实体类。

以下代码演示了如何用Newtonsoft还原包含嵌套地址信息的对象,并展示忽略某些属性的做法。我们在项目中需先通过包管理器安装Newtonsoft.Json,然后在文件顶部引用using Newtonsoft.Json;

using System;
using Newtonsoft.Json;

public class Address
{
    public string City { get; set; }
}

public class Person
{
    [JsonProperty("user_name")]
    public string UserName { get; set; }

    [JsonIgnore]
    public int InternalId { get; set; }

    public Address Home { get; set; }
}

class Test
{
    static void Main()
    {
        string json = "{"user_name":"李四","Home":{"City":"北京"}}";
        Person p = JsonConvert.DeserializeObject<Person>(json);
        Console.WriteLine(p.UserName + "来自" + p.Home.City);
    }
}

从该示例可见,Newtonsoft对非常规结构容忍度更高,且社区资料丰富。不过它基于反射的机制在超高并发场景下分配内存较多,若系统追求极致吞吐,应评估是否切换至原生库或采用Source Generator方案。

处理异常与日期格式等常见坑点

反序列化并非总能一帆风顺,网络抖动、字段缺失、类型不符都会引发异常。System.Text.Json在解析失败时抛出JsonException,而Newtonsoft通常抛JsonReaderExceptionJsonSerializationException。生产代码中应当用try-catch包裹反序列化调用,并记录原始字符串以便排查,而不是让异常直接中断请求管线。

另一个高频问题是日期格式。JSON标准并未规定日期写法,有的接口用2024-03-01,有的用时间戳,有的带时区偏移。原生库可通过JsonConverter自定义解析逻辑,Newtonsoft则能在JsonSerializerSettings里设置DateFormatString。若忽略这一层,默认反序列化可能把时间变成本地时区的错误值,导致业务计算偏差。

下面示例用System.Text.Json演示如何编写一个处理特定日期格式的转换器,并注册到选项中。这样当遇到yyyy/MM/dd这类非标准文本时,依然能正确还原为DateTime。

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public class CustomDateConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.ParseExact(reader.GetString(), "yyyy/MM/dd", null);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy/MM/dd"));
    }
}

public class Order
{
    public string Product { get; set; }

    [JsonConverter(typeof(CustomDateConverter))]
    public DateTime CreateDate { get; set; }
}

class Demo
{
    static void Main()
    {
        string json = "{"Product":"键盘","CreateDate":"2024/03/01"}";
        Order o = JsonSerializer.Deserialize<Order>(json);
        Console.WriteLine(o.Product + "下单于" + o.CreateDate.ToShortDateString());
    }
}

除了日期,数字类型不一致也是隐患。例如接口把ID写成字符串"1001"而模型定义为long,原生库会直接报错。此时要么调整模型为string,要么在转换器里做类型兼容。明确接口契约、在网关层做格式校验,能从源头减少这类反序列化故障。

C#JSON反序列化Newtonsoft修改时间:2026-08-18 07:34:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。