当.NET抛出WebException ((400) Bad Request)时,如何处理WebResponse?

41

我正在使用 Facebook Graph API 并尝试获取用户数据。我发送了用户访问令牌,如果此令牌已过期或无效,则 Facebook 将返回状态代码 400 并返回以下响应:

{
    "error": {
        "message": "Error validating access token: The session is invalid because the user logged out.",
        "type": "OAuthException"
    }
}

问题是当我使用以下这段 C# 代码时:

try {
   webResponse = webRequest.GetResponse(); // in case of status code 400 .NET throws WebException here
} catch (WebException ex) {
}
如果状态码为400,.NET会抛出WebException异常,异常被捕获后我的webResponse变量就会变成null,这样我就没有机会处理它了。我想要处理它以确保问题是由过期的令牌引起的,而不是其他地方引起的。有办法做到吗?谢谢。
2个回答

101

使用try/catch块,并适当处理错误消息应该可以正常工作:

    var request = (HttpWebRequest)WebRequest.Create(address);
    try {
        using (var response = request.GetResponse() as HttpWebResponse) {
            if (request.HaveResponse && response != null) {
                using (var reader = new StreamReader(response.GetResponseStream())) {
                    string result = reader.ReadToEnd();
                }
            }
        }
    }
    catch (WebException wex) {
        if (wex.Response != null) {
            using (var errorResponse = (HttpWebResponse)wex.Response) {
                using (var reader = new StreamReader(errorResponse.GetResponseStream())) {
                    string error = reader.ReadToEnd();
                    //TODO: use JSON.net to parse this string and look at the error message
                }
            }
        }
    }
}

然而,使用Facebook C# SDK可以轻松实现该功能,无需自己进行处理。


感谢您详细的回答,我已经以类似的方式完成了它。我知道我可以使用Facebook SDK,但与Google或Twitter相比,使用Facebook API相对容易,因此我决定在这里手动完成所有操作,以便理解流程并拥有更多的控制。 - Burjua
有人知道为什么在Silverlight中WebException --> errorResponse.GetResponseStream()为空吗?虽然我可以在Fiddler中看到响应主体。 - Ismael
我也是 null。正在进行一些调查。在正常的 .net 编译时,这个工作是按预期进行的。 - Ross Jones
似乎丢失WebException->errorResponse的问题来自于using块。根据此答案中给出的建议,如果只在流周围使用using块,则不会丢失errorResponse。 - ksaylor11

14

WebExceptioncatch 代码块中仍然可以通过 Response 属性访问“真实”的响应数据(如果有响应的话)。


谢谢Jon,尝试访问Response属性是个好主意吗?如果我在catch块内部遇到异常会发生什么?我应该将我的try and catch放在另一个try and catch中吗? - Burjua
@Burjua:访问该属性不会引发异常 - 毕竟这就是它的作用。我相信响应已经包含了所有响应数据,因此如果您成功获取了响应流,则读取响应流本身应该是安全的。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接