如何从HttpRequestException获取StatusCode?


87

我可能在这里缺少明显的东西。

我正在使用Message字符串中包含的HttpClient引发。HttpRequestExceptionStatusCode

我该如何访问StatusCode呢?


编辑:更多信息,我急着写了这个问题。

HttpClient用来访问WebApi项目中的另一个API。是的,我知道为什么要打电话EnsureSuccessStatusCode()。我想向下游传播一些错误,例如404和403。

我想要的是始终如一地转换HttpRequestExceptionHttpResponseException使用custom ExceptionFilterAttribute

不幸的是,HttpRequestException除了消息之外,我没有任何其他可用的信息。我希望以StatusCode原始(int或枚举)形式发现。

看起来我可以:

  1. 使用该消息切换状态代码(正常)
  2. 或创建我的SecureSuccessStatusCode版本并引发实际上可用的异常。

1
您可以显示一段代码吗?
Hamlet Hakobyan 2014年

1
“访问该状态代码”是什么意思?
Marco Marco

显示代码,告诉您从哪里获取异常。
丹麦2014年

5
伙计们,这个问题的标题不清楚吗?
库格尔2014年

1
您是否找到了解决此问题的适当方法?请分享
Siddharth Pandey 2014年

Answers:


37

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

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

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

如果您现在正在遵循Microsoft指南,请确保您清楚地理解了为什么它要求您致电HttpResponseMessage.EnsureSucessStatusCode。如果您不调用该函数,则不应有例外。


2
我在这里试图解决一个跨领域的问题。看我的编辑,也许有更好的解决方案。
Kugel 2014年

1
这是否适合使用HttpClient.GetStreamAsync(url),因为我看不到一种无需剥离消息文本即可执行此操作的方法?
参议员

1
@TheSenator您必须调用GetAsync(uri)或PostAsync(uri)来获取HttpResponseMessage。如果尝试通过读取响应或使用便捷方法(如GetStreamAsync)来获取响应的内容,则在后台调用sureSuccessStatusCode。
odyth

6
这就引出了一个显而易见的问题:便捷方法抛出异常而无法有效地处理错误的根本意义是什么?用if和throw语句乱扔代码不是解决方案,因此从这里所说的看来,当前的正确答案是您必须自己重新实现便捷方法或sureSuccessStatusCode。
Neutrino

1
说起来容易做起来难。可以从第三方代码引发异常。例如自动生成的摇摇欲坠的客户端。
user2555515

27

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

在需要异常状态属性的情况下,可以执行以下操作:

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

    return false;
}

14
投票,因为有时您无权访问响应,例如当您被迫使用包装功能并引发任何异常的库时。
凯尔(Kell)

4
.net核心2.1 HttpClient具有GetAsync()和GetStreamAsync()。第一个将返回响应,而另一个将在内部调用sureSucessStatusCode并抛出HttpRequestException。我不理解这种不一致,这使处理错误变得困难,但是我很欣赏这种解决方法。
smurtagh,

2
正在运行.NET Core 3.1.5,requestException.InnerException因此为null,因此将无法正常工作
Ohad Schneider

3

正如其他人所提到的,从HttpRequestException获取StatusCode也不是一个好习惯,在检查HttpResponseMessage.IsSuccessStatusCode之后,也可以使用HttpResponseMessage.StatusCode进行相同的操作。

无论如何,如果由于某种限制/要求,一个人必须读取StatusCode,可以有两种解决方案

  1. 使用您在此处说明的自定义异常扩展了HttpResponseMessage
  2. 攻击HttpRequestException.ToString以获得StatusCode,因为消息是由StatusCode和Repharse固定的固定帖子。

下面是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
具有特定格式的错误字符串是代码的味道,逻辑永远不应依赖于它们。
user1496062

1
@ user1496062当错误来自外部系统时,通常别无选择。
伊恩·沃伯顿

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.