如何从HttpRequestException获取StatusCode?

时间:2014-03-06 07:13:33

标签: c# dotnet-httpclient httpexception

我可能在这里遗漏了一些明显的东西。

我正在使用HttpClient,它会在消息字符串中抛出包含HttpRequestException的{​​{1}}。

如何访问StatusCode


修改:更多信息,我急着写下这个问题。

我正在使用StatusCode访问我的WebApi项目中的另一个API。是的,我知道为什么我打电话给HttpClient。我想向下游传播一些错误,例如404和403。

我想要的是使用自定义EnsureSuccessStatusCode()始终如一地将HttpRequestException转换为HttpResponseException

不幸的是,ExceptionFilterAttribute除了邮件之外没有我可以使用的任何额外信息。我希望以原始(int或enum)形式发现HttpRequestException

看起来我可以:

  1. 使用该消息切换状态代码(bleh)
  2. 或者创建我的EnsureSuccessStatusCode版本并抛出实际可用的异常。

6 个答案:

答案 0 :(得分:28)

状态代码作为字符串的一部分传递给HttpRequestException,因此您无法仅从此类异常中恢复它。

System.Net.Http的设计要求您访问HttpResponseMessage.StatusCode,而不是等待例外。

http://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage(v=vs.110).aspx

如果您现在关注the Microsoft guide,请确保明白为什么要求您致电HttpResponseMessage.EnsureSucessStatusCode。如果你没有调用那个函数,那么应该没有例外。

答案 1 :(得分:18)

为了它的价值,这个家伙做了一些聪明的事情: https://social.msdn.microsoft.com/Forums/vstudio/en-US/dc9bc426-1654-4319-a7fb-383f00b68def/c-httpresponsemessage-throws-exception-httprequestexception-webexception-the-remote-name?forum=csharpgeneral

在我需要异常状态属性的情况下,我可以这样做:

catch (HttpRequestException requestException)
{
    if (requestException.InnerException is WebException && 
      ((WebException)requestException.InnerException).Status == WebExceptionStatus.NameResolutionFailure)
    {
        return true;
    }

    return false;
}

答案 2 :(得分:5)

也许我来晚了:

从 .NET 5.0 开始, ui.write(r'python -m idlelib C:\User\USERS\Documents\split.py',interval=0.023) 有一个 HttpRequestException 属性,如果异常表示不成功的结果,该属性将具有一个值,否则为 null。所以你可以使用如下:

StatusCode

更多详情请见here

答案 3 :(得分:3)

正如其他人所提到的,从HttpRequestException获取StatusCode并不是一个好习惯,在检查HttpResponseMessage.IsSuccessStatusCode后,可以事先用HttpResponseMessage.StatusCode做同样的事情

无论如何,如果由于某些约束/要求,必须读取StatusCode, 可以有两个解决方案

  1. 使用自定义异常here
  2. 扩展了HttpResponseMessage
  3. 使用HttpRequestException.ToString来获取StatusCode,因为消息是由StatusCode和Repharse修复​​的常量帖子。
  4. 以下是System.Net.Http.HttpResponseMessage中的代码 其中SR.net_http_message_not_success_statuscode =“响应状态代码未指示成功:{0}({1})。”

    public HttpResponseMessage EnsureSuccessStatusCode()
        {
            if (!this.IsSuccessStatusCode)
            {
                if (this.content != null)
                {
                    this.content.Dispose();
                }
                throw new HttpRequestException(string.Format(CultureInfo.InvariantCulture, SR.net_http_message_not_success_statuscode, new object[]
                {
                    (int)this.statusCode,
                    this.ReasonPhrase
                }));
            }
            return this;
        }
    

答案 4 :(得分:2)

这对我有用

var response = ex.Response;
var property = response.GetType().GetProperty("StatusCode");
if ( property != null && (HttpStatusCode)property.GetValue(response) == HttpStatusCode.InternalServerError)

答案 5 :(得分:0)

对于 .Net Core 3.1,我无法使用 TanvirArjel 或 Lex Li 的解决方案。所以我手动调用 HttpClient 的 GetHttpAsync 方法并自己询问 Http 状态代码。如果状态代码返回“OK”,我会为返回的 Html 处理 HttpClient 的 Content 属性。

public async Task<string> GetHtml(string url)
{
    int retry = 3;

    while (retry > 0)
    {
        retry = retry - 1;

        try
        {   
            var result = await client.GetAsync(url);
            if (result.StatusCode != HttpStatusCode.OK)
            {
                switch (result.StatusCode)
                {
                    case HttpStatusCode.BadGateway:
                    case HttpStatusCode.BadRequest:
                    case HttpStatusCode.Forbidden:
                    case HttpStatusCode.ServiceUnavailable:
                    case HttpStatusCode.GatewayTimeout:
                        {
                            Global.Report($"CustomHttpClient: Temporary issue detected. Pausing to allow time to resolve.");
                            // Wait for temporary issue to resolve
                            await Task.Delay(120000);
                            continue;
                        }
                    default:
                        {
                            throw new Exception($"CustomHttpClient: Error {result.StatusCode}.");
                        }
                }
            }
            string response = await result.Content.ReadAsStringAsync();
            return response;
        }
        catch (Exception ex)
        {
            throw new Exception($"CustomHttpClient: Error downloading page => {url}. " + ex);
        }
    }

    throw new Exception($"CustomHttpClient: Temporary issue persists. Retries exhausted. Unable to download page => {url}.");
}