首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正确使用EnsureSuccessStatusCode和IsSuccessStatusCode

正确使用EnsureSuccessStatusCode和IsSuccessStatusCode
EN

Stack Overflow用户
提问于 2017-08-17 15:50:38
回答 3查看 22.5K关注 0票数 6

我使用HttpClient调用Web,我看到有一个EnsureSuccessStatusCode方法和一个IsSuccessStatusCode属性。哪一个合适?

我读了这篇文章,还有几个问题:

Usage of EnsureSuccessStatusCode and handling of HttpRequestException it throws

我遇到的问题是,如果我在传递要检索对象的ID的地方发送GET请求,基本上有两种结果:

  1. 我得到状态为200的对象。
  2. 我可以获得null返回,因为没有匹配,但是这会导致404的状态。

如果我将EnsureSuccessStatusCode()称为状态404,则会引发异常。这并不理想,因为当我测试我的代码时,我一直收到404错误,这让我最初认为API URL是不正确的,但实际上没有匹配的对象与提供的Id。在这种情况下,我宁愿返回一个空对象,而不是抛出异常。

因此,我尝试检查IsSuccessfulStatusCode属性的值。这似乎是一个更好的选择,当该属性为false时,我可以返回一个空对象,但是,有许多状态代码可以导致该属性具有一个假值。404是其中之一,但是还有其他几个状态代码,例如400坏请求405方法不允许等等。我想记录所有不成功错误代码的异常(404除外),我想知道是否有比检查响应的ResponseCode值,然后抛出一个被我的catch块捕获的异常(也就是日志记录发生的地方)更好的方法。

下面是我的GET方法的代码:

代码语言:javascript
运行
复制
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;
        }
    }

如果返回一个不成功的状态代码,并且没有任何记录,则此代码将只返回一个空Customer

处理这种情况的最佳方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-08-17 16:49:16

正因如此:

因此,我尝试检查IsSuccessfulStatusCode属性的值。这似乎是一个更好的选择,当该属性为false时,我可以返回一个空对象,但是,有许多状态代码可以导致该属性具有一个假值。404是其中之一,但是还有其他几个状态代码,例如400坏请求、405个不允许的方法等等。除了404之外,我想为所有不成功的错误代码记录一个异常,我想知道是否有更好的方法来做到这一点:检查响应的ResponseCode值,然后抛出一个异常,它会被我的catch块捕获,这就是日志记录发生的地方。

我将使用EnsureSuccessStatusCode方法,然后修改catch块,如下所示:

代码语言:javascript
运行
复制
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;
    }
}
票数 5
EN

Stack Overflow用户

发布于 2020-11-25 10:53:55

accepted answer使用“异常分支”,这被一些人认为是反模式。下面是如何使用EnsureSuccessStatusCodeIsSuccessStatusCode的一种方法,即只对意外或不能或不应该“本地”处理的错误使用异常:

  1. 如果要处理特定的错误响应,请直接使用if-statements.处理它们。
  2. 如果希望将所有(剩余的)错误响应视为意外错误,请使用EnsureSuccessStatusCode不捕获异常,但假设它将由实际能够对其执行某些操作的catch处理程序处理(例如更高级别的应用程序逻辑或通用顶级错误处理程序)。
  3. 如果您想对所有(剩余的)错误响应(如日志记录)做一些事情,但是要正常进行,或者如果您想抛出您自己类型的异常,请使用IsSuccessStatusCode

这种方法为您提供了异常的所有优点,同时最大限度地减少了缺点(例如在您可能不感兴趣的完全正常事件上中断调试器,或者用catch块填充代码,这些语句比if-语句更难读和写)。

示例:

代码语言:javascript
运行
复制
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
  }
}

..。或者,如果您想要读取错误响应或进行日志记录,等等:

代码语言:javascript
运行
复制
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
  }
}
票数 7
EN

Stack Overflow用户

发布于 2020-09-07 21:04:20

根据本文档:https://learn.microsoft.com/en-us/windows/uwp/networking/httpclient可以在以下解决方案中正常:

代码语言:javascript
运行
复制
Uri requestUri = new Uri("http://www.contoso.com");

//Send the GET request asynchronously and retrieve the response as a string.
Windows.Web.Http.HttpResponseMessage httpResponse = new 
Windows.Web.Http.HttpResponseMessage();
string httpResponseBody = "";

try
{
    //Send the GET request
    httpResponse = await httpClient.GetAsync(requestUri);
    httpResponse.EnsureSuccessStatusCode();
    httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
    httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}

但是: httpResponse.EnsureSuccessStatusCode();==状态代码从200到299

我使用HttpStatusCode.OK = 200 = is作为EnsureSuccessStatusCode的子部分,并指示请求成功,所请求的信息在响应中。

代码语言:javascript
运行
复制
HttpResponseMessage result = await this._httpClient.GetAsync("https://www.web1.com/getThis", cancellationToken);
if (result.StatusCode != HttpStatusCode.OK)
{
    return new HttpResponseMessage(result.StatusCode)
    {
        Content = new StringContent( "ERROR DESCRIPTION HERE")
    };
}
return result;  // I can return here HttpResponseMessage....
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45739753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档