无法反序列化从 Webapi 返回的 ProblemDetails

问题描述 投票:0回答:1

我有两个用 C# 编写的微服务,在 .NET 8.0 上运行。

  1. WebApiOne
    有一个
    GlobalHandler
    实现
    IExceptionHandler
    返回以下内容:

    var problemDetails = new ProblemDetails
                             {
                                 Status = statusCode,
                                 Title = title,
                                 Extensions = new Dictionary<string, object?>
                                      {
                                          { "errors", new[] { errors?.ToArray()} },
                                          { "traceId", traceId }
                                      }
                             };
    
    httpContext.Response.StatusCode = statusCode;
    
    await httpContext.Response.WriteAsJsonAsync<ProblemDetails>(problemDetails, cancellationToken);
    
  1. WebApiTwo
    中,我调用
    WebApiOne
    ,如果不成功,我将
    response.Content
    反序列化为
    ProblemDetails
    ,如下所示:

    ProblemDetails problem = JsonConvert.DeserializeObject<ProblemDetails>(response.Content);
    

    这次没有成功!当我检查

    response.Content
    时,我看到返回了以下 json

{
"problemDetails":{"type":"https://tools.ietf.org/html/rfc9110#section-15.5.5","title":"Not Found","status":404,"errors":["Company xxxxx not found."],"traceId":"00-e30d5f33ee2885874ab4faf827e0f660-117cedba6f2a3368-00"},"contentType":"application/problem+json","statusCode":404
}

我期待 ProblemDetails 不是一个名为“problemDetails”的属性,这是正常行为吗?

如果没有,有解决方案吗?,我想反序列化为 ProblecDetals 对象

asp.net-core-webapi json-deserialization .net-8.0
1个回答
0
投票

根据你的描述,我自己写了一个测试demo,效果很好,因为你没有提供如何创建异常处理程序以及如何使用httpclient调用这个web api,你可以参考我的代码并测试用我的代码。

我的测试演示如下:

问题详情

public class ProblemDetails
{
    public string Status { get; set; }

    public string Title { get; set; }


    public Dictionary<string, object?> Extensions { get; set; }
}

自定义异常处理程序:

public class CustomExceptionHandler : IExceptionHandler
{
    private readonly ILogger<CustomExceptionHandler> logger;
    public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
    {
        this.logger = logger;
    }
    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        var problemDetails = new ProblemDetails
        {
            Status = "404",
            Title = "test",
            Extensions = new Dictionary<string, object?>
            {
                                  { "errors", new[] { "Company xxxxx not found." } },
                { "traceId", "xxxxxxxxxxxxxxxxxxxxxxx" }
                              }
        };

        httpContext.Response.StatusCode = StatusCodes.Status404NotFound;

        await httpContext.Response.WriteAsJsonAsync<ProblemDetails>(problemDetails, cancellationToken);

        return false;
    }
}

我的客户代码:

        var client = new HttpClient();
        client.BaseAddress = new Uri("https://localhost:7231/");
        client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/problem+json"));
        var url = "WeatherForecast";
        var response =   client.GetAsync(url).Result;
        var responseBody =   response.Content.ReadAsStringAsync().Result;
        var result = JsonConvert.DeserializeObject<ProblemDetails>(responseBody);

结果:

© www.soinside.com 2019 - 2024. All rights reserved.