区分 HttpClient 请求失败类型

Posted

技术标签:

【中文标题】区分 HttpClient 请求失败类型【英文标题】:Distinguish between HttpClient request failure types 【发布时间】:2013-06-26 16:55:55 【问题描述】:

我需要编写代码来处理使用 .Net Framework 4.5 附带的 HttpClient 对象发出 HTTP 请求后可能出现的两种不同类型的故障:

    连接失败,当由于连接问题而无法访问服务器时 - 例如。无可用连接、超时过期、网络设置不正确等

    虽然技术上不是失败,但请求成功到达服务器但服务器响应 HTTP 错误状态码(例如 404、400、409、500 等)的情况

不要将一种故障类型视为另一种,这一点非常重要。哪种方法是正确和可靠的? EnsureSuccessStatusCode() 方法似乎至少对第二种情况有所帮助,但令人失望的是文档很少。

【问题讨论】:

【参考方案1】:

经过一些手动测试后,好消息是似乎有一种可靠的方法来区分这两种错误,但坏消息是它在所有平台上并非始终相同——至少在 Windows Phone 8 上不是. 在 .Net Framework 4.5 Full 和 Windows Store App 类型的项目上,以下代码可以解决问题:

        try
        
            var response = await httpClient.PostAsync(uri, content);

            if (!response.IsSuccessStatusCode)
            
                // handle the second type of error (404, 400, etc.)
            
        
        catch (HttpRequestException ex)
        
            // handle the first type of error (no connectivity, etc)
        

不幸的是,在 Windows Phone 8 上,这两种类型都是在 if 条件下处理的:IsSuccessStatusCode 设置为 false,并且不会引发 HttpRequestException(或任何其他异常)。对于 WP8,我使用的是 HttpClient (http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx) 的可移植类库实现,我问他们是否可以修复这种不一致,希望它可以并且很快就会解决。

【讨论】:

这种方法的问题在于,您需要在这个(可能是实用程序)方法中拥有异常处理逻辑,而不是让这个方法的客户端能够处理这两个条件。此外,EnsureSuccessStatusCode() 看起来也抛出了相同的异常类型HttpRequestException使得“客户”更难区分。更糟糕的是,我似乎找到了一种从异常中提取 http 状态代码的方法。我想可以通过编写和抛出自定义异常来处理,但感觉框架中缺少了一些东西。 看起来不一致仍然存在。你有没有找到区分无连接和合法 404 的方法? @rmorrin:如果我没记错的话,如果失败是由与服务器的连接引起的,则响应对象的“ReasonPhrase”字符串属性为空(或空)。这并不理想,但我没有注意到任何其他可以用来区分它们的东西——至少在行为上看起来是一致的。

以上是关于区分 HttpClient 请求失败类型的主要内容,如果未能解决你的问题,请参考以下文章

httpclient 学习

httpclient怎么发送请求并携带Cookie

WebApi系列~HttpClient的性能隐患 - 转

基于httpclient的效率优化

高并发场景下的httpClient优化使用

HttpClient 异步请求失败