You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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配置中指定使用该转换器:

  1. 在项目中创建自定义转换器:
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));
    }
}
  1. 在NSwag配置中指定使用该转换器:
{
  "CSharpGeneratorSettings": {
    "JsonConverters": [
      {
        "TypeName": "YourNamespace.CustomDateConverter",
        "Type": "DateTimeOffset"
      }
    ],
    // 其他已有配置...
  }
}

这种方式可以完全控制日期序列化逻辑,且不会被生成文件覆盖,稳定性更高。


内容的提问来源于stack exchange,提问作者monadoboi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 14:46:07