为什么当响应是 HTML 而不是 JSON 时 HttpClient.GetFromJsonAsync 不会引发异常?

发布于 2025-01-10 02:47:46 字数 1393 浏览 0 评论 0原文

我正在学习 Blazor。 我使用“ASP.NET Core Hosted”选项创建了一个 Blazor WASM 应用程序。 所以我的解决方案中有 3 个项目:客户端、服务器和共享。

以下代码位于客户端项目中,当端点正确时(显然),它可以完美工作。但在某些时候我犯了一个错误,弄乱了请求 URI,然后我注意到 API 返回了一个 HTML 页面,代码为 200 OK(正如您在代码下方的 Postman 屏幕截图中看到的那样)。

我预计我的一个 try-catch 会得到这个结果,但调试器跳转到最后一行(返回 null)而不会引发异常。

我的第一个问题是为什么?

我的第二个问题是我怎样才能抓住这个?

我知道修复端点可以解决所有问题,但是如果有一个捕获器可以在我输入错误的 URI 时提醒我,那就太好了。

谢谢。

private readonly HttpClient _httpClient;
public async Task<List<Collaborator>> GetCollaborators()
{
    string requestUri = "api/non-existent-endpoint";
    try
    {
        var response = await _httpClient.GetFromJsonAsync<CollaboratorsResponse>(requestUri);
        if (response == null) 
        {
            // It never enters here. Jumps to the last line of code.
        }
        return response.Collaborators;
    }
    catch (HttpRequestException)
    {
        Console.WriteLine("An error occurred.");
    }
    catch (NotSupportedException)
    {
        Console.WriteLine("The content type is not supported.");
    }
    catch (JsonException)
    {
        Console.WriteLine("Invalid JSON.");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return null;
}

邮差截图

I'm learning Blazor.
I have created a Blazor WASM App with the "ASP.NET Core Hosted" option.
So I have 3 projects in the solution: Client, Server and Shared.

The following code is in the Client project and works perfectly when the endpoint is correct (obviously). But at some point I made a mistake and messed up the request URI, and then I noticed that the API returned an HTML page with code 200 OK (as you can see in the Postman screenshot below the code).

I expected one of my try-catches to get this, but the debugger jumps to the last line (return null) without throwing an exception.

My first question is why?

My second question is how can I catch this?

I know fixing the endpoint fixes everything, but would be nice to have a catch that alerts me when I have mistyped an URI.

Thanks.

private readonly HttpClient _httpClient;
public async Task<List<Collaborator>> GetCollaborators()
{
    string requestUri = "api/non-existent-endpoint";
    try
    {
        var response = await _httpClient.GetFromJsonAsync<CollaboratorsResponse>(requestUri);
        if (response == null) 
        {
            // It never enters here. Jumps to the last line of code.
        }
        return response.Collaborators;
    }
    catch (HttpRequestException)
    {
        Console.WriteLine("An error occurred.");
    }
    catch (NotSupportedException)
    {
        Console.WriteLine("The content type is not supported.");
    }
    catch (JsonException)
    {
        Console.WriteLine("Invalid JSON.");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return null;
}

Postman Screenshot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淤浪 2025-01-17 02:47:46

使用 GetFromJsonAsync 从来都不是一个好主意。您不是第一个询问这种奇怪行为的人。尝试使用 GetAsync。那么至少你会知道,发生了什么。

var response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
    var stringData = await response.Content.ReadAsStringAsync();
    var result = JsonConvert.DeserializeObject<CollaboratorsResponse>(stringData);
    ... your code
} 
else
{
    var statusCode = response.StatusCode.ToString(); // HERE is your error status code, when you have an error
}

It is never a good idea to use GetFromJsonAsync. You are not the first who is asking about the strange behavior. Try to use GetAsync. Then at least you will know, what is going on.

var response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
    var stringData = await response.Content.ReadAsStringAsync();
    var result = JsonConvert.DeserializeObject<CollaboratorsResponse>(stringData);
    ... your code
} 
else
{
    var statusCode = response.StatusCode.ToString(); // HERE is your error status code, when you have an error
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文