简体   繁体   English

读取WebException的响应流

[英]Reading the response stream of a WebException

I have the following method which is basically authenticating users with their Facebook credentials. 我有以下方法,基本上使用他们的Facebook凭据验证用户。 For some reason, I am getting a WebException when trying to process the authorization key (code). 出于某种原因,我在尝试处理授权密钥(代码)时收到WebException So I tried to read the response stream in order to know what is going on but I keep getting errors while reading the stream. 所以我试着读取响应流以便知道发生了什么,但是在读取流时我一直遇到错误。 Here's my code: 这是我的代码:

    private void OnAuthCallback(HttpContextWrapper context, WebServerClient client)
    {
        try
        {
            IAuthorizationState authorizationState = client.ProcessUserAuthorization(context.Request);
            AccessToken accessToken = AccessTokenSerializer.Deserialize(authorizationState.AccessToken);
            String username = accessToken.User;
            context.Items[USERNAME] = username;
        }
        catch (ProtocolException e)
        {
            if (e.InnerException != null)
            {
                String message = e.InnerException.Message;
                if (e.InnerException is WebException)
                {
                    WebException exception = (WebException)e.InnerException;
                    var responseStream = exception.Response.GetResponseStream();
                    responseStream.Seek(0, SeekOrigin.Begin);
                    using (StreamReader sr = new StreamReader(responseStream))
                    {
                        message = sr.ReadToEnd();
                    }
                }
                EventLog.WriteEntry("OAuth Client", message);
            }
        }
    }

If I remove the responseStream.Seek(0, SeekOrigin.Begin); 如果我删除了responseStream.Seek(0, SeekOrigin.Begin); line, it gives me an ArgumentException with a message that says the stream was not readable. 它给了我一个ArgumentException其中包含一条消息,说明该流不可读。 And with this line in place, it tells me that I cannot manipulate a stream that was already closed. 有了这条线,它告诉我,我无法操纵已经关闭的流。 How was this stream closed? 这条小溪是怎么关闭的? And why can't I read from it? 为什么我不能从中读取?

You can read the body of the response. 您可以阅读回复的正文。 I've found the solution in this answer . 我在这个答案中找到了解决方案。

You should cast the stream to MemoryStream and use ToArray method, then use Encoding.UTF8.GetString to get text. 您应该将流转换为MemoryStream并使用ToArray方法,然后使用Encoding.UTF8.GetString来获取文本。

private void OnAuthCallback(HttpContextWrapper context, WebServerClient client)
{
    try
    {
        IAuthorizationState authorizationState = client.ProcessUserAuthorization(context.Request);
        AccessToken accessToken = AccessTokenSerializer.Deserialize(authorizationState.AccessToken);
        String username = accessToken.User;
        context.Items[USERNAME] = username;
    }
    catch (ProtocolException e)
    {
        if (e.InnerException != null)
        {
            String message = e.InnerException.Message;
            if (e.InnerException is WebException)
            {
                WebException exception = (WebException)e.InnerException;
                message = ExtractResponseString(webException);
            }
            EventLog.WriteEntry("OAuth Client", message);
        }
    }
}

public static string ExtractResponseString(WebException webException)
{
    if (webException == null || webException.Response == null)
        return null;

    var responseStream = 
        webException.Response.GetResponseStream() as MemoryStream;

    if (responseStream == null)
        return null;

    var responseBytes = responseStream.ToArray();
    var responseString = Encoding.UTF8.GetString(responseBytes);
    return responseString;
}

It looks like you are using DotNetOpenAuth. 看起来你正在使用DotNetOpenAuth。 Unfortunately I think this library closes the response stream of the WebException before wrapping it in the ProtocolException that your code receives. 不幸的是,我认为这个库在将它包装在你的代码收到的ProtocolException之前关闭了WebException的响应流。 You can enable logging at the DEBUG level to have the response dumped to a log file, but I don't think you'll find any way to access it from your code. 您可以在DEBUG级别启用日志记录以将响应转储到日志文件,但我认为您无法从代码中找到任何方法来访问它。

One of the DotNetOpenAuth devs describes the situation here : 其中一个DotNetOpenAuth开发者描述了这里的情况:

DotNetOpenAuth closes the HTTP response stream while handling and throwing the wrapped exception because if DNOA didn't close the stream, your open streams allotment would fill up and then your app would start hanging. DotNetOpenAuth在处理和抛出包装的异常时关闭HTTP响应流,因为如果DNOA没有关闭流,您的开放流分配将填满,然后您的应用将开始挂起。 DNOA does write the response stream's content to its log if I recall correctly. 如果我没记错的话,DNOA会将响应流的内容写入其日志。

Things may have changed in the latest (unreleased) version of DNOA (5.0), as the part of the code that is causing the problem in the current release version has been removed. 最新(未发布)版本的DNOA(5.0)中的内容可能已更改,因为已删除导致当前发行版本中的问题的代码部分。

a WebException can have different causes and the server isn't always required to return a body under certain (error-)circumstance thus no response.stream. WebException可能有不同的原因,并且服务器并不总是需要在某些(错误)情况下返回正文,因此没有response.stream。

Have a look at the returned status-code first 首先看看返回的状态代码

Another tool to help you investigate what's going is Fiddler 另一个帮助你调查Fiddler的工具是Fiddler

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM