Des*_*xAZ 3 c# exception-handling httpresponse asp.net-web-api
我正在调用我的Web API HttpClient
,我看到有一个EnsureSuccessStatusCode
方法和一个IsSuccessStatusCode
属性.哪一个合适?
我读了这篇文章,还有一些问题:
使用EnsureSuccessStatusCode并处理它抛出的HttpRequestException
我遇到的问题是,如果我发送一个GET请求,我传递了ID
我想要检索的对象,基本上有两个结果:
如果我调用EnsureSuccessStatusCode()
状态404将导致抛出异常.这并不理想,因为当我测试我的代码时,我一直收到404错误,这首先让我觉得API URL不正确,但实际上没有匹配的对象与提供的Id.在这种情况下,我宁愿返回一个null对象而不是抛出异常.
所以我尝试检查IsSuccessfulStatusCode
属性的值.这似乎是一个更好的选择,当此属性为false时,我可以返回一个null对象,但是,有许多状态代码可能导致此属性具有false值.404是其中之一,但还有其他几个状态代码,例如400 Bad Request,405 Method Not Allowed等.我想记录除404之外的所有不成功的错误代码的异常,我想知道是否有一种更好的方法可以做到这一点,而不是检查ResponseCode
响应的值,然后抛出一个由我的catch块捕获的异常,这是记录发生的地方.
这是我的GET方法的代码:
public static Customer GetCustomerByID(int id)
{
try
{
using (var client = GetConfiguredClient())
{
Customer customer = null;
var requestUri = $"Customers/{id}";
using (var response = client.GetAsync(requestUri).Result)
{
if (response.IsSuccessStatusCode)
customer = response.Content.ReadAsAsync<Customer>().Result;
}
return customer;
}
}
catch (Exception ex)
{
ex.Data.Add(nameof(id), id);
LogException(ex);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
Customer
如果返回非成功的状态代码并且没有记录任何内容,则此代码将返回null .
处理这种情况的最佳方法是什么?
Flo*_*ter 10
接受的答案采用“异常分支”,这被一些人认为是反模式。以下是如何使用EnsureSuccessStatusCode
和 ,IsSuccessStatusCode
仅针对意外或不能或不应“本地”处理的错误使用异常:
EnsureSuccessStatusCode
并且不捕获异常,但假设它将由实际上可以执行某些操作的 catch 处理程序处理(例如更高级别的应用程序逻辑,或通用顶级错误处理程序)。IsSuccessStatusCode
.这种方法为您提供了异常的所有优点,同时最大限度地减少了缺点(例如,在您可能不感兴趣的完全正常的事件上中断调试器,或者用 catch 块填充代码,这些块比 if 更难读写-声明)。
例子:
using (var response = client.GetAsync(requestUri).Result)
{
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
// TODO: Special handling for "401 Unauthorized" goes here
}
else
{
// All other unsuccessful error codes throw
response.EnsureSuccessStatusCode();
// TODO: Handling of successful response goes here
}
}
Run Code Online (Sandbox Code Playgroud)
...或者如果您想读取错误响应或进行日志记录等:
using (var response = client.GetAsync(requestUri).Result)
{
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
// TODO: Special handling for "401 Unauthorized" goes here
}
else if (!response.IsSuccessStatusCode)
{
// TODO: Read error response, logging, throw custom exception, etc., goes here
// TODO: Keep this if you still want to throw the standard exception.
// TODO: Otherwise, remove this.
response.EnsureSuccessStatusCode();
}
else
{
// TODO: Handling of successful response goes here
}
}
Run Code Online (Sandbox Code Playgroud)
因为这:
所以我尝试检查
IsSuccessfulStatusCode
属性的值.这似乎是一个更好的选择,当此属性为false时,我可以返回一个null对象,但是,有许多状态代码可能导致此属性具有false值.404是其中之一,但还有其他几个状态代码,例如400 Bad Request,405 Method Not Allowed等.我想记录除404之外的所有不成功的错误代码的异常,我想知道是否有一种更好的方法可以做到这一点,而不是检查ResponseCode
响应的值,然后抛出一个由我的catch块捕获的异常,这是记录发生的地方.
我会使用该EnsureSuccessStatusCode
方法,然后修改catch
块,如下所示:
public static Customer GetCustomerByID(int id)
{
try
{
using (var client = GetConfiguredClient())
{
var requestUri = $"Customers/{id}";
Customer customer;
using (var response = client.GetAsync(requestUri).Result)
{
try
{
response.EnsureSuccessStatusCode();
// If we reach here it means we can get the customer data.
customer = response.Content.ReadAsAsync<Customer>().Result;
}
catch(HttpRequestException)
{
if(response.StatusCode == HttpStatusCode.NotFound) // 404
{
customer = null;
}
else
{
throw;
}
}
}
return customer;
}
}
catch (Exception ex)
{
ex.Data.Add(nameof(id), id);
LogException(ex);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)