C# 读取WebException的响应流

C# 读取WebException的响应流,c#,asp.net,facebook,stream,dotnetopenauth,C#,Asp.net,Facebook,Stream,Dotnetopenauth,我有下面的方法,基本上是用用户的Facebook凭据验证用户。由于某些原因,我在尝试处理授权密钥(代码)时遇到WebException。因此,我试图读取响应流以了解发生了什么,但在读取流时不断出错。这是我的密码: private void OnAuthCallback(HttpContextWrapper context, WebServerClient client) { try { IAuthorizationState

我有下面的方法,基本上是用用户的Facebook凭据验证用户。由于某些原因,我在尝试处理授权密钥(代码)时遇到
WebException
。因此,我试图读取响应流以了解发生了什么,但在读取流时不断出错。这是我的密码:

    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);
            }
        }
    }

如果我删除
responseStream.Seek(0,SeekOrigin.Begin)行,它给我一个
ArgumentException
,其中有一条消息说流不可读。有了这条线,它告诉我,我不能操纵一个已经关闭的流。这条小溪是怎么关闭的?为什么我不能从中读取呢?

WebException可能有不同的原因,并且在某些(错误)情况下,服务器并不总是需要返回正文,因此没有响应.stream

首先查看返回的状态代码


另一个帮助您调查情况的工具是

,看起来您正在使用DotNetOpenAuth。不幸的是,我认为这个库在将WebException封装到代码接收的ProtocolException中之前关闭了WebException的响应流。您可以在调试级别将响应转储到日志文件,但我认为您无法从代码中访问它

其中一个DotNetOpenAuth开发人员描述了这种情况:

DotNetOpenAuth在处理和抛出包装异常时关闭HTTP响应流,因为如果DNOA没有关闭该流,则您的OpenStreams分配将填满,然后您的应用程序将开始挂起。如果我没有记错,DNOA会将响应流的内容写入日志


在DNOA(5.0)的最新(未发布)版本中,情况可能发生了变化,因为导致当前版本中出现问题的代码部分已被删除。

您可以阅读响应正文。我已经找到了解决办法

您应该将流强制转换为
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;
}

@Iboshuizen:状态为
协议错误
。您是否尝试fiddler查看从客户端到服务器以及返回的响应信息?这是其中一个我希望能够给出多个赞成票的实例。