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

.NET 8 Blazor Web App调用独立API返回null求助排查

问题排查:Blazor WASM调用API返回数据但客户端接收null

我采用.NET 8 Blazor Web Application模板创建了包含服务端渲染、WASM及AUTO模式的解决方案(内含服务端与客户端项目),同时存在一个独立的API解决方案用于从数据库获取数据。客户端通过Program.cs中配置的HttpClient调用该API,调试时可见API接收请求并返回数据,但客户端服务始终收到null值,请求排查原因。

客户端服务代码

namespace Dispatch.Client.Services
{
    public class DispatchAPI : IDispatchAPI
    {
        private readonly HttpClient httpClient;

        public DispatchAPI(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }
        public async Task<List<ProductionMinutesByDay>> GetProductionMinutesSeriesAsync(string department, DateTime? startDate, DateTime? endDate)
        {
            try
            {                    
                var request = new HttpRequestMessage(HttpMethod.Get, $"/ProdMinutes/ProdMinutes?department={department}&startDate={startDate}&enddate={endDate}");
                request.SetBrowserRequestMode(BrowserRequestMode.NoCors);
                var response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    var prodMinStr = response.Content.ReadAsStream();
                    var prodMin = JsonSerializer.Deserialize<List<ProductionMinutesByDay>>(prodMinStr);
                    return prodMin;
                }
                throw new Exception(response.StatusCode.ToString());


            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString);
                return null;
            }

        }
    }
}

客户端Program.cs代码

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSyncfusionBlazor();
builder.Services.AddSingleton<IDispatchAPI, DispatchAPI>();
builder.Services.AddHttpClient<IDispatchAPI, DispatchAPI>(client =>
{
    client.BaseAddress = new Uri("https://localhost:7239");
});

await builder.Build().RunAsync();

API控制器代码

namespace DispatchAPI.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class ProdMinutesController: ControllerBase
    {
        private readonly IProdMinutesRepository _repository;
        private readonly IConfiguration _configuration;

        public ProdMinutesController(IProdMinutesRepository repository, IConfiguration configuration)
        {
            _repository = repository;
            _configuration = configuration;
        }

        [HttpGet("ProdMinutes")]
        public async Task<List<ProdMinutesDayDTO>> ProdMinutes(string? department, DateTime startDate, DateTime enddate)
        {
            var prodMinSeries = await _repository.GetProdMinutesSeriesAsync(JdeUtility.PadDepartment(department), JdeUtility.ConvertDateToJulian(startDate), JdeUtility.ConvertDateToJulian(enddate));
            return prodMinSeries;
        }
    }
}

可能的原因及解决方案

1. CORS配置错误

客户端设置了BrowserRequestMode.NoCors,这会让浏览器限制读取API响应内容——即使API返回了数据,浏览器也会阻止客户端访问响应体,最终反序列化得到null。

  • 解决:移除request.SetBrowserRequestMode(BrowserRequestMode.NoCors);,在API项目中配置CORS策略:
    // API项目Program.cs
    builder.Services.AddCors(options =>
    {
        options.AddPolicy("BlazorClient", policy =>
        {
            policy.WithOrigins("https://localhost:5001") // 替换为你的Blazor客户端地址
                  .AllowAnyHeader()
                  .AllowAnyMethod();
        });
    });
    
    // 在UseRouting之后添加
    app.UseCors("BlazorClient");
    

2. 实体类与DTO不匹配

API返回的是List<ProdMinutesDayDTO>,但客户端反序列化用的是List<ProductionMinutesByDay>,如果两类的属性名称、类型不匹配(比如大小写差异、字段缺失),JsonSerializer会反序列化失败返回null。

  • 解决:
    • 确保两类属性完全一致;
    • 或者在反序列化时启用大小写不敏感配置:
      var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
      var prodMin = JsonSerializer.Deserialize<List<ProductionMinutesByDay>>(prodMinStr, options);
      

3. 异常日志未正确输出

代码中Debug.WriteLine(ex.ToString);少了括号,应该是ex.ToString(),导致无法看到反序列化失败的具体异常信息,难以定位问题。

  • 解决:修正为Debug.WriteLine(ex.ToString());,查看输出窗口的异常详情。

4. 日期参数格式问题

URL中的日期参数格式可能不符合API预期,虽然API能接收请求,但可能处理后返回空数据(不过你提到API已返回数据,这条优先级较低)。

  • 解决:显式指定日期格式,比如:
    var url = $"/ProdMinutes/ProdMinutes?department={department}&startDate={startDate:yyyy-MM-dd}&enddate={endDate:yyyy-MM-dd}";
    

5. 简化HttpClient调用

可以直接使用GetFromJsonAsync简化代码,同时自动处理序列化配置:

public async Task<List<ProductionMinutesByDay>> GetProductionMinutesSeriesAsync(string department, DateTime? startDate, DateTime? endDate)
{
    try
    {                    
        var url = $"/ProdMinutes/ProdMinutes?department={department}&startDate={startDate:yyyy-MM-dd}&enddate={endDate:yyyy-MM-dd}";
        var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
        var prodMin = await httpClient.GetFromJsonAsync<List<ProductionMinutesByDay>>(url, options);
        return prodMin ?? throw new Exception("返回数据为空");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.ToString());
        return null;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:52:53