用于反序列化的自定义转换器未触发或未在 Web 中达到断点 API

Custom converter for deserialization not firing or not hitting break point in Web API

我有这样的转换器

class MultiFormatDateConverter : JsonConverter
{
    public List<string> DateTimeFormats { get; set; }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        string dateString = (string)reader.Value;
        DateTime date;
        foreach (string format in DateTimeFormats)
        {
            // adjust this as necessary to fit your needs
            if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                return date;
        }
        throw new System.Text.Json.JsonException("Unable to parse \"" + dateString + "\" as a date.");
    }
}

这是配置

var settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new MultiFormatDateConverter
    {
         DateTimeFormats = new List<string> { "yyyyMMddTHHmmssZ", "yyyy-MM-ddTHH:mm","MMMM yyyy","dd/MM/yyyy","dd/MM/yy","MMM-yy","MMM yy" 
     }
 });

我是这样称呼它的:

List<KipReport> rpt730 = JsonConvert.DeserializeObject<List<KipReport>>(responseBody, settings);

这是JSON和class

[
  {
    "Name":"Alex",
    "MonthWorked":"January 2021",
    "LastEdtDate":"16/02/2021",
    "LastEditBy":"san"
  }
]
class KipReport
{
    public string Name { get; set; }
    public DateTime? MonthWorked { get; set; }
    public DateTime? LastEditDate { get; set; }
}

我的是一个网络 API,这里是调用函​​数的控制器。请注意,它将函数调用为 Task.Run()

[HttpGet]
public async Task<IActionResult> Get()
{
    await Task.Run(()=>_kReport.GetKReports());
    
    return Accepted();
}

执行时说

16/03/2021 is not a valid date format

然后我使用这种方式进行转换而不是转换器

var settings = new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" };

那么错误是 January 2021 is not a valid date

意思是,不考虑转换器??

因为我有不同的日期格式,所以我使用了一个转换器。

那么对于 Web API/Task。运行 我们是否需要为自定义转换器做任何特定的事情?

您的属性属于 DateTime? 类型(即 nullable value types) so in CanConvert 您必须检查 objectType == typeof(DateTime?) 以及 objectType == typeof(DateTime)。然后,在 Read() 中,如果传入的 objectTypetypeof(DateTime?) 如果 JSON 令牌为空,您应该 return null

以下固定转换器执行此操作并跳过注释:

class MultiFormatDateConverter : JsonConverter
{
    public List<string> DateTimeFormats { get; set; } = new ();

    public override bool CanConvert(Type objectType) => 
        objectType == typeof(DateTime) || objectType == typeof(DateTime?);

    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) => throw new NotImplementedException();

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        if (reader.MoveToContent().TokenType == JsonToken.Null)
            return objectType == typeof(DateTime?) ? null : throw new System.Text.Json.JsonException("Unable to parse null as a date.");
        else if (reader.TokenType != JsonToken.String)
            throw new System.Text.Json.JsonException("Unable to parse token \"" + reader.TokenType + "\" as a date.");
        string dateString = (string)reader.Value;
        foreach (string format in DateTimeFormats)
        {
            // adjust this as necessary to fit your needs
            if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date))
                return date;
        }
        throw new System.Text.Json.JsonException("Unable to parse \"" + dateString + "\" as a date.");
    }
}

public static partial class JsonExtensions
{
    public static JsonReader MoveToContent(this JsonReader reader)
    {
        while ((reader.TokenType == JsonToken.Comment || reader.TokenType == JsonToken.None) && reader.Read())
            ;
        return reader;
    }
}

备注:

  • 在您的 JSON 中,您有一个名为 "LastEdtDate" 的 属性,而相应的 c# 属性 是 LastEditDate。 JSON 属性 名称在 Edit 中缺少字母 i 等不受 c# 属性 的束缚。我认为这是问题中的错字,但如果不是,则需要将 [JsonProperty("LastEdtDate")] 添加到 LastEditDate.

演示 fiddle here.