Json.NET序列化日期格式差异问题

本文介绍了如何使用Newtonsoft.Json库解决在序列化过程中日期格式出现的问题,通过自定义IsoDateTimeConverter并设置DateTimeFormat属性来避免时间戳和时区差异。

Newtonsoft.Json在转换日期的时候,会出现格式和时区(差8小时)差别


如果不作格式转换,会出现形如Date(1335247957000+0800)/的日期


IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
//这里使用自定义日期格式,如果不使用的话,默认是ISO8601格式
timeConverter.DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";

string jsonStr = JsonConvert.SerializeObject(list, Formatting.Indented, timeConverter);


<think>嗯,用户正在问如何在.NET Core中进行JSON序列化和反序列化,包括具体方法和使用指南。用户明确要求了解实现方式和使用指引。 先看用户提供的引用信息: [1]提到ASP.NET Core默认使用Json.NET处理JSON(实际上这个信息有些过时,需要留意); [2]和[3]说明从.NET Core 3.0开始默认使用System.Text.Json(这个才是最新默认方案); [3]给出了具体的配置方法示例; [4]对比了System.Text.JsonJson.NET的性能差异; [5]则展示了空值处理代码实例。 思考如何组织回答: 1️⃣ 基础概念需澄清:必须明确说明.NET Core 3.0+默认使用System.Text.Json这个关键变化(引用[2][3]) 2️⃣ 实操部分分三个层次: 基本操作要覆盖:模型定义、序列化/反序列化核心代码(JsonSerializer方法) 配置部分整合引用[3]的重要配置项(编码、日期格式、命名策略等) 特殊处理需说明空值和循环引用引用[5]的示例 3️⃣ 性能对比部分直接引用[4]的结论,但补充说明选择原则 4️⃣ 高级应用要提及动态类型和文档模型(JsonDocument/JsonNode) 5️⃣ 最后给出直观的总结表格 需注意技术细节: ▸ 序列化方法:JsonSerializer.Serialize ▸ 反序列化方法:JsonSerializer.Deserialize ▸ 中文编码配置的Encoder设置必须强调(常见问题) ▸ 日期格式转换器示例需实用 ▸ JsonPropertyName特性的使用场景 ▸ 异步流处理对于大文件很重要 可能衍生的疑问点: - Newtonsoft.Json兼容性(通过AddNewtonsoftJson拓展) - 异步方法与同步方法选择 - 实际性能数据差异(可提示基准测试工具BenchmarkDotNet) 整理回答结构: ■ 开头明确核心方案(System.Text.Json) ■ 分步代码演示基础操作 ■ 重点展开配置方法(代码示例) ■ 高级场景列举 ▸ 最后用表格对比两种库 ◆ 生成问题要覆盖迁移方案、异常处理、性能瓶颈等实际问题 准备在回复时强调: ⚠ 中文乱码解决方案(JavaScriptEncoder.Create) ⚠ 日期格式化最佳实践 ⚠ 空值处理的两种模式(忽略/包含) 最后生成的问题会侧重实际开发中常见的配置、迁移和调试需求。 </think> 在 .NET Core 中,JSON 序列化主要通过 **System.Text.Json**(默认)或 **Json.NET(Newtonsoft.Json)** 库实现。以下是详细指南: --- ### 一、默认方案:System.Text.Json(推荐) 从 **.NET Core 3.0+** 起,官方默认集成此高性能序列化器。 #### 1. 基础用法 ```csharp using System.Text.Json; // 模型定义 public class Book { public string Title { get; set; } public string Author { get; set; } public DateTime PublishDate { get; set; } } // 序列化(对象 → JSON) Book book = new Book { Title = "Effective C#", Author = "Bill Wagner" }; string json = JsonSerializer.Serialize(book); // 反序列化JSON → 对象) Book deserializedBook = JsonSerializer.Deserialize<Book>(json); ``` #### 2. 关键配置(`AddJsonOptions`) 在 `Program.cs` 中自定义行为: ```csharp builder.Services.AddControllers() .AddJsonOptions(options => { // 解决中文编码问题 options.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All); // 日期格式化 options.JsonSerializerOptions.Converters.Add(new DateTimeConverter("yyyy-MM-dd HH:mm:ss")); // 属性命名策略(默认camelCase,设为null保持原名) options.JsonSerializerOptions.PropertyNamingPolicy = null; // 忽略循环引用 options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; }); ``` #### 3. 自定义转换器 处理特殊类型(如自定义日期格式): ```csharp public class DateTimeConverter : JsonConverter<DateTime> { private readonly string _format; public DateTimeConverter(string format) => _format = format; public override DateTime Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) => DateTime.ParseExact(reader.GetString(), _format, CultureInfo.InvariantCulture); public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(_format)); } ``` #### 4. 空值处理 ```csharp // 序列化时忽略空值属性 options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; // 反序列化时检测空值(.NET 6+) JsonElement element = JsonDocument.Parse(json).RootElement; if (element.TryGetProperty("title", out JsonElement title) && title.ValueKind == JsonValueKind.Null) { Console.WriteLine("检测到空值"); } ``` --- ### 二、使用 Json.NET(Newtonsoft.Json) 如需兼容旧项目或使用高级功能,需手动安装 `Microsoft.AspNetCore.Mvc.NewtonsoftJson` 包。 #### 1. 启用方法 ```csharp builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; }); ``` #### 2. 功能对比 | **特性** | **System.Text.Json** | **Json.NET** | |------------------------|------------------------------------------|----------------------------| | **默认版本** | .NET Core 3.0+ | 需手动安装 | | **性能** | 快 20-30%(原生设计)[^4] | 较慢 | | **循环引用处理** | `ReferenceHandler.IgnoreCycles` | `PreserveReferencesHandling` | | **复杂自定义** | 有限(需手动实现转换器) | 丰富(如 `ContractResolver`)| | **动态类型支持** | 基础(`JsonNode`) | 完善(`JObject`/`JArray`) | --- ### 三、使用建议 1. **优先选 System.Text.Json** 适用于高性能 API、新项目,满足大部分场景 [^2][^4]。 2. **需要复杂特性时用 Json.NET** 如:多态序列化、深度自定义契约解析。 3. **异步流处理大文件** ```csharp await JsonSerializer.SerializeAsync(responseStream, largeData); ``` --- ### 四、常见问题解决 - **中文乱码**:配置 `JavaScriptEncoder.Create(UnicodeRanges.All)` [^3]。 - **日期格式化**:自定义 `JsonConverter`。 - **忽略属性**:使用 `[JsonIgnore]` 特性。 - **字段名映射**:`[JsonPropertyName("title")]`(System.Text.Json)或 `[JsonProperty("title")]`(Json.NET)。 --- ### 性能优化提示 - 避免频繁创建 `JsonSerializerOptions`(全局复用配置实例)。 - 大文件用 `Utf8JsonReader/Utf8JsonWriter` 进行流处理。 - 预编译序列化器(AOT 场景):`JsonSerializer.SerializeToUtf8Bytes()` > 示例代码引用自配置实践指南 [^3][^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值