.NET 8:使用GetFromJsonAsync返回可空int时遇JsonException问题
能否用GetFromJsonAsync返回可空int?返回null时抛出JsonException错误
当API返回null时,调用GetFromJsonAsync<int?>会抛出System.Text.Json.JsonException,提示“输入不包含任何JSON令牌”,想实现返回null而非0。
API端点代码
[HttpGet("BusinessId")] public async Task<int?> BusinessId(int userId, CancellationToken token) { var businessId = await _businessService.GetDefaultBusinessId(userId, token); return businessId; }
调用方代码
public async Task<int?> GetDefaultBusinessId(int userId, CancellationToken token) { var url = $"https://localhost:7000/Business/BusinessId?userId={userId}"; var businessId = await client.GetFromJsonAsync<int?>(url, token); return businessId; }
更新1
这是采用InteractiveAuto渲染模式的Blazor Web应用。
更新2
- 浏览器响应头:Content-Type为
text/plain; charset=utf-8,状态码200 - 改用
GetStringAsync调用时,返回空字符串
API配置代码
builder.Services.AddControllers(o => { o.InputFormatters.Insert(0, KoJPIF.GetJsonPatchInputFormatter()); }).AddNewtonsoftJson();
问题根源
当API返回null时,ASP.NET Core默认会返回空响应体(没有任何JSON内容),而GetFromJsonAsync<int?>要求输入是有效的JSON令牌(比如null字符串),空响应体不符合JSON格式,因此抛出异常。另外,你配置的NewtonsoftJson默认也不会在返回null时输出null字符串,而是返回空响应。
解决办法
办法1:修改API,显式返回JSON格式的null
把API端点改为返回JsonResult,确保即使值为null也输出JSON格式的null:
[HttpGet("BusinessId")] public async Task<IActionResult> BusinessId(int userId, CancellationToken token) { var businessId = await _businessService.GetDefaultBusinessId(userId, token); return Json(businessId); }
这样当businessId为null时,API会返回null字符串,GetFromJsonAsync<int?>就能正确解析为null。
办法2:在调用方手动处理空响应
如果不想修改API,可以先获取响应内容,判断为空后直接返回null:
public async Task<int?> GetDefaultBusinessId(int userId, CancellationToken token) { var url = $"https://localhost:7000/Business/BusinessId?userId={userId}"; var response = await client.GetAsync(url, token); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(token); if (string.IsNullOrWhiteSpace(content)) { return null; } return System.Text.Json.JsonSerializer.Deserialize<int?>(content); }
办法3:全局配置NewtonsoftJson返回null
在API的NewtonsoftJson配置中,设置NullValueHandling.Include,让所有返回null的端点都输出JSONnull:
builder.Services.AddControllers(o => { o.InputFormatters.Insert(0, KoJPIF.GetJsonPatchInputFormatter()); }).AddNewtonsoftJson(options => { options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include; });
注意:这个配置是全局生效的,会影响所有返回null的API接口。
内容的提问来源于stack exchange,提问作者GH DevOps
相关产品推荐
相关产品推荐

