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

.NET Web API/Blazor中DateTime序列化与反序列化异常排查

Blazor应用无法正常反序列化DateTime的原因及解决办法

问题描述

我希望在Blazor应用中显示服务器时间,当前实现步骤如下:

控制器代码

[HttpGet]
public Task<DtoValue<DateTime>> GetServerLocalTime() 
     => Task.FromResult(new DtoValue<DateTime>(DateTime.Now));

对应的DtoValue类

public class DtoValue<T>
{
    public DtoValue()
    {
    }

    public DtoValue(T? value)
    {
        Value = value;
    }

    public T? Value;
}

Program.cs配置

在Program.cs中已添加Newtonsoft配置:

builder.Services.AddControllers()
    .AddNewtonsoftJson();

Web API返回结果

Web API返回的JSON数据为:

{
  "value": "2023-01-16T23:13:53.0037535+01:00"
}

异常情况

但在Blazor应用中使用以下代码反序列化时:

var dtoTimeValue = await HttpClient.GetFromJsonAsync<DtoValue<DateTime>>("api/Hello/GetServerLocalTime").ConfigureAwait(false);

得到的dtoTimeValue中DateTime为默认值1/1/0001 12:00:00 AM。

而手动使用Newtonsoft.Json反序列化时则正常:

var result = await HttpClient.GetAsync("api/Hello/GetServerLocalTime").ConfigureAwait(false);
var resultString = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
var dtoTimeValue = JsonConvert.DeserializeObject<DtoValue<DateTime>>(resultString);

原因分析

核心问题在于序列化/反序列化工具的规则不匹配:

  • 后端API使用Newtonsoft.Json(Json.NET)序列化数据,但Blazor中HttpClient.GetFromJsonAsync默认采用的是System.Text.Json。
  • DtoValue<T>类中的Value是字段而非属性,System.Text.Json默认仅处理带getter/setter的属性,不会序列化或反序列化字段;而Newtonsoft.Json默认支持字段的序列化/反序列化,这就是两种方式结果不同的直接原因。

解决办法

方案1:将字段改为属性

修改DtoValue<T>类,把Value字段替换为带getter和setter的属性,让System.Text.Json可以识别并处理:

public class DtoValue<T>
{
    public DtoValue()
    {
    }

    public DtoValue(T? value)
    {
        Value = value;
    }

    public T? Value { get; set; }
}

方案2:让HttpClient使用Newtonsoft.Json反序列化

如果不想修改类结构,可以为Blazor的HttpClient封装Newtonsoft.Json的反序列化逻辑:

  1. 为Blazor项目安装Newtonsoft.Json NuGet包。
  2. 添加自定义扩展方法:
public static class HttpClientExtensions
{
    public static async Task<T?> GetFromNewtonsoftJsonAsync<T>(this HttpClient client, string requestUri)
    {
        var response = await client.GetAsync(requestUri).ConfigureAwait(false);
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        return JsonConvert.DeserializeObject<T>(content);
    }
}
  1. 在Blazor中使用该扩展方法替代默认的GetFromJsonAsync:
var dtoTimeValue = await HttpClient.GetFromNewtonsoftJsonAsync<DtoValue<DateTime>>("api/Hello/GetServerLocalTime").ConfigureAwait(false);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:40:23