状态码不成功时无法读取 HttpResponseMessage 内容
Can't read HttpResponseMessage content when the status code is not success
我有一项服务使用 HttpClient
:
使用 SMS REST API
HttpClient http = this._httpClientFactory.CreateClient();
// Skipped: setup HttpRequestMessage
using (HttpResponseMessage response = await http.SendAsync(request))
{
try
{
_ = response.EnsureSuccessStatusCode();
}
catch (HttpRequestException)
{
string responseString = await response.Content.ReadAsStringAsync(); // Fails with ObjectDisposedException
this._logger.LogInformation(
"Received invalid HTTP response status '{0}' from SMS API. Response content was {1}.",
(int)response.StatusCode,
responseString
);
throw;
}
}
API returns 一个错误,但我希望能够记录它。所以我需要记录失败状态代码(我可以从 response.StatusCode
中读取)和相关内容(可能包含其他错误有用的详细信息)。
此代码在指令 await response.Content.ReadAsStringAsync()
上失败,但出现以下异常:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpConnection+HttpConnectionResponseContent'.
Module "System.Net.Http.HttpContent", in CheckDisposed
Module "System.Net.Http.HttpContent", in ReadAsStringAsync
一些消息来源建议当状态码不在成功范围 (200-299) 内时,您不应阅读响应内容,但如果响应确实包含有用的错误详细信息怎么办?
.NET 使用版本:AWS lambda linux 运行时上的 .NET Core 2.1.12。
好的,显然这是 .NET API 中的 a known issue,它已在 .NET Core 3.0 中得到解决。 response.EnsureSuccessStatusCode()
实际上是在处理响应内容。它以这种方式实现,据说可以帮助用户:
// Disposing the content should help users: If users call EnsureSuccessStatusCode(), an exception is
// thrown if the response status code is != 2xx. I.e. the behavior is similar to a failed request (e.g.
// connection failure). Users don't expect to dispose the content in this case: If an exception is
// thrown, the object is responsible fore cleaning up its state.
这是一种不良行为,已从 3.0 中删除。与此同时,我只是在日志之前切换到使用IsSuccessStatusCode
:
HttpClient http = this._httpClientFactory.CreateClient();
// Skipped: setup HttpRequestMessage
using (HttpResponseMessage response = await http.SendAsync(request))
{
if (!response.IsSuccessStatusCode)
{
string responseString = await response.Content.ReadAsStringAsync(); // Fails with ObjectDisposedException
this._logger.LogInformation(
"Received invalid HTTP response status '{0}' from SMS API. Response content was {1}.",
(int)response.StatusCode,
responseString
);
_ = response.EnsureSuccessStatusCode();
}
}
有点多余,但应该可以。
我有一项服务使用 HttpClient
:
HttpClient http = this._httpClientFactory.CreateClient();
// Skipped: setup HttpRequestMessage
using (HttpResponseMessage response = await http.SendAsync(request))
{
try
{
_ = response.EnsureSuccessStatusCode();
}
catch (HttpRequestException)
{
string responseString = await response.Content.ReadAsStringAsync(); // Fails with ObjectDisposedException
this._logger.LogInformation(
"Received invalid HTTP response status '{0}' from SMS API. Response content was {1}.",
(int)response.StatusCode,
responseString
);
throw;
}
}
API returns 一个错误,但我希望能够记录它。所以我需要记录失败状态代码(我可以从 response.StatusCode
中读取)和相关内容(可能包含其他错误有用的详细信息)。
此代码在指令 await response.Content.ReadAsStringAsync()
上失败,但出现以下异常:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.HttpConnection+HttpConnectionResponseContent'.
Module "System.Net.Http.HttpContent", in CheckDisposed
Module "System.Net.Http.HttpContent", in ReadAsStringAsync
一些消息来源建议当状态码不在成功范围 (200-299) 内时,您不应阅读响应内容,但如果响应确实包含有用的错误详细信息怎么办?
.NET 使用版本:AWS lambda linux 运行时上的 .NET Core 2.1.12。
好的,显然这是 .NET API 中的 a known issue,它已在 .NET Core 3.0 中得到解决。 response.EnsureSuccessStatusCode()
实际上是在处理响应内容。它以这种方式实现,据说可以帮助用户:
// Disposing the content should help users: If users call EnsureSuccessStatusCode(), an exception is
// thrown if the response status code is != 2xx. I.e. the behavior is similar to a failed request (e.g.
// connection failure). Users don't expect to dispose the content in this case: If an exception is
// thrown, the object is responsible fore cleaning up its state.
这是一种不良行为,已从 3.0 中删除。与此同时,我只是在日志之前切换到使用IsSuccessStatusCode
:
HttpClient http = this._httpClientFactory.CreateClient();
// Skipped: setup HttpRequestMessage
using (HttpResponseMessage response = await http.SendAsync(request))
{
if (!response.IsSuccessStatusCode)
{
string responseString = await response.Content.ReadAsStringAsync(); // Fails with ObjectDisposedException
this._logger.LogInformation(
"Received invalid HTTP response status '{0}' from SMS API. Response content was {1}.",
(int)response.StatusCode,
responseString
);
_ = response.EnsureSuccessStatusCode();
}
}
有点多余,但应该可以。