在 JSON.net 的自定义 JsonConverter 中读取原始日期字符串

Read raw Date string in a Custom JsonConverter of JSON.net

我有一个 ISO 8601 格式的输入日期字符串 (2020-07-23T09:42:02.694Z)。在我的控制器中,属性 被定义为 DateTime。我已经编写了一个自定义日期转换器来将日期转换为本地时区(这很不寻常)。

public class UTCtoUnspecifiedDateConverter : IsoDateTimeConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader != null 
            && reader.Value != null 
            && this.CanConvert(objectType) 
            && this.CanRead 
            && typeof(DateTime) == reader.Value.GetType())
        {
            return DateTime.SpecifyKind((DateTime)reader.Value, DateTimeKind.Unspecified).ToLocalTime();
        }
        else
        {
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
    }
}

有什么方法可以在这个转换器中获取我从客户端发送的原始字符串吗?
基本上我想检查最后是否有 Z

在调试时我在 reader 上看到一个 private 属性 来存储这些信息。有什么办法可以得到这个吗?

如果您使用自定义 JsonConverter 来处理日期,则需要将 DatePraseHandling 设置设为 None

var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.Converters.Add(new UTCtoUnspecifiedDateConverter());
jsonSettings.DateParseHandling = DateParseHandling.None;

然后,在您的转换器中,您将从 reader 中获取日期值作为字符串,您可以使用 DateTime.TryParseDateTime.TryParseExact.

进行解析

顺便说一句,您在 ReadJson 内部进行了一些不必要的检查。您不需要调用 CanConvertCanRead,因为 Json.Net 会为您执行此操作,以便首先确定是否调用 ReadJson。此外,传递给 ReadJsonreader 永远不会为空,因此您也不需要检查它。这样就大大简化了代码。

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.Value is string && 
        DateTime.TryParseExact((string)reader.Value, DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
    {
        return DateTime.SpecifyKind(date, DateTimeKind.Unspecified).ToLocalTime();
    }
    else
    {
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }
}