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

.NET Core 3.1 XUnit测试本地通过 Azure DevOps报Json反序列化错误

问题排查步骤
  • 第一步:先补全请求状态校验,同时打印Azure环境下的接口实际返回内容
    你当前代码没有判断查询接口的请求是否成功,直接读取返回内容反序列化。可以在反序列化前加入代码:Assert.True(response.IsSuccessStatusCode, $"查询接口请求失败,状态码:{response.StatusCode},返回内容:{responseString}"),运行Azure DevOps测试后从日志中提取返回的实际内容,确认是不是异常时返回的错误对象(比如ASP.NET Core默认的ProblemDetails结构)、或者加了全局响应包装的结构、或者接口返回结构从数组改成了单个对象。
    注意:你本地调试时贴出的responseString是HttpResponseMessage的ToString结果,不是接口实际返回的业务JSON,说明你本地调试时看错了返回内容,这个结构本身就不是数组,反序列化本来就会失败,说明你本地可能是因为接口实际返回内容和你看到的不一致才跑通
  • 第二步:检查/api/Campaign/find?title=Test接口的逻辑
    确认接口有没有兼容无匹配数据的场景:如果没有匹配的Campaign时接口返回了单个null、NotFound对象,而不是空数组[],就会触发反序列化错误。另外确认是不是Azure环境的接口版本和本地不一致,返回结构从数组改成了单个对象。
  • 第三步:检查Azure环境的中间件配置
    确认是不是加了全局响应包装中间件,把所有接口返回都包成了{code:200, data:[], msg:"success"}这类结构,你直接反序列化外层对象自然会失败,本地没加这类中间件所以能正常跑通。
解决方案
  1. 调整测试代码,补全校验逻辑,示例如下:
[Fact]
public async Task RemoveCampaign_RemoveOneCampaignIsSuccessWhenCampaignIdIsValid()
{
    var client = _factory.CreateClient();

    var response = await client.GetAsync("/api/Campaign/find?title=Test");
    var responseString = await response.Content.ReadAsStringAsync();
    // 提前校验请求状态,出错直接打印返回内容
    Assert.True(response.IsSuccessStatusCode, $"查询接口异常,返回内容:{responseString}");

    List<CampaignResponseDto> resultList;
    try
    {
        resultList = JsonConvert.DeserializeObject<List<CampaignResponseDto>>(responseString);
    }
    catch (JsonSerializationException ex)
    {
        // 序列化失败时抛出详细信息方便排查
        throw new InvalidOperationException($"反序列化失败,实际返回内容:{responseString}", ex);
    }
    
    var result = resultList.FirstOrDefault();
    Assert.IsType<CampaignResponseDto>(result);

    if (result != null)
    {
        var deleteResponse = await client.DeleteAsync($"/api/Campaign/{result.Id}");
        // 修复原来的断言错误:你之前写的是校验查询请求的状态,应该校验删除请求的状态
        Assert.True(deleteResponse.IsSuccessStatusCode);
        Assert.Equal(HttpStatusCode.Accepted, deleteResponse.StatusCode);
    }
}
  1. 如果排查发现Azure环境加了全局响应包装,定义对应的包装类,先反序列化包装类再取数据字段的数组即可。
  2. 如果是接口无匹配数据时返回结构不统一,调整接口逻辑,无数据时统一返回空数组[]即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 14:57:02