NSwag自动生成DTO时字符串类型date格式的实现问题
NSwag生成Date格式DTO的问题与解决方法
问题场景
我使用NSwag基于YAML生成DTO,YAML定义如下:
User: type: object additionalProperties: false properties: createdAt: type: string format: date
生成的C# DTO代码:
[System.Text.Json.Serialization.JsonPropertyName("createdAt")] [System.Text.Json.Serialization.JsonConverter(typeof(DateFormatConverter))] public System.DateTimeOffset CreatedAt { get; set; } = default!;
自动生成的DateFormatConverter类:
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.15.10.0 (NJsonSchema v10.6.10.0 (Newtonsoft.Json v13.0.0.0))")] internal class DateFormatConverter : System.Text.Json.Serialization.JsonConverter<System.DateTime> { public override System.DateTime Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { var dateTime = reader.GetString(); if (dateTime == null) { throw new JsonException("Unexpected JsonTokenType.Null"); } return System.DateTime.Parse(dateTime); } public override void Write(System.Text.Json.Utf8JsonWriter writer, System.DateTime value, System.Text.Json.JsonSerializerOptions options) { writer.WriteStringValue(value.ToString("yyyy-MM-dd")); } }
遇到的问题:JsonException提示“未找到”,手动添加using System.Text.Json;可解决,但生成文件会在构建时被覆盖,该using语句会丢失。需要解决两个问题:
- 有没有更优的date格式实现方式?
- 能否通过配置自动添加该using语句?
解决方法
1. 自动添加Using语句的配置方案
在NSwag的配置文件(如nswag.json)中,通过调整代码生成设置,可自动为生成的转换器类添加所需的using语句:
找到CSharpGeneratorSettings节点,添加Namespaces配置项,将System.Text.Json加入其中:
{ "CSharpGeneratorSettings": { "Namespaces": [ "System.Text.Json" ], // 其他已有配置... } }
这样生成的文件会自动包含using System.Text.Json;,无需手动添加,避免构建时丢失。
2. 更优的Date格式实现方式
方案一:使用内置日期转换器
NSwag支持直接配置使用System.Text.Json内置的日期处理逻辑,无需自定义转换器。在YAML保持format: date的同时,修改NSwag配置中的JsonSerializerSettings:
{ "CSharpGeneratorSettings": { "JsonSerializerSettings": { "DateFormatString": "yyyy-MM-dd", "DateParseHandling": "DateTimeOffset" }, // 其他已有配置... } }
生成的DTO属性会直接使用内置的日期序列化逻辑,避免自定义转换器带来的问题。
方案二:自定义全局转换器替代生成的转换器
如果需要统一的日期格式处理,可以在项目中手动编写全局日期转换器,然后在NSwag配置中指定使用该转换器:
- 在项目中创建自定义转换器:
using System; using System.Text.Json; using System.Text.Json.Serialization; public class CustomDateConverter : JsonConverter<DateTimeOffset> { private const string DateFormat = "yyyy-MM-dd"; public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (!DateTimeOffset.TryParseExact(reader.GetString()!, DateFormat, null, System.Globalization.DateTimeStyles.None, out var result)) { throw new JsonException("Invalid date format. Expected yyyy-MM-dd."); } return result; } public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString(DateFormat)); } }
- 在NSwag配置中指定使用该转换器:
{ "CSharpGeneratorSettings": { "JsonConverters": [ { "TypeName": "YourNamespace.CustomDateConverter", "Type": "DateTimeOffset" } ], // 其他已有配置... } }
这种方式可以完全控制日期序列化逻辑,且不会被生成文件覆盖,稳定性更高。
内容的提问来源于stack exchange,提问作者monadoboi
相关产品推荐
相关产品推荐

