簡體   English   中英

讀取WebException的響應流

[英]Reading the response stream of a WebException

我有以下方法,基本上使用他們的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其中包含一條消息,說明該流不可讀。 有了這條線,它告訴我,我無法操縱已經關閉的流。 這條小溪是怎么關閉的? 為什么我不能從中讀取?

您可以閱讀回復的正文。 我在這個答案中找到了解決方案。

您應該將流轉換為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;
}

看起來你正在使用DotNetOpenAuth。 不幸的是,我認為這個庫在將它包裝在你的代碼收到的ProtocolException之前關閉了WebException的響應流。 您可以在DEBUG級別啟用日志記錄以將響應轉儲到日志文件,但我認為您無法從代碼中找到任何方法來訪問它。

其中一個DotNetOpenAuth開發者描述了這里的情況:

DotNetOpenAuth在處理和拋出包裝的異常時關閉HTTP響應流,因為如果DNOA沒有關閉流,您的開放流分配將填滿,然后您的應用將開始掛起。 如果我沒記錯的話,DNOA會將響應流的內容寫入其日志。

最新(未發布)版本的DNOA(5.0)中的內容可能已更改,因為已刪除導致當前發行版本中的問題的代碼部分。

WebException可能有不同的原因,並且服務器並不總是需要在某些(錯誤)情況下返回正文,因此沒有response.stream。

首先看看返回的狀態代碼

另一個幫助你調查Fiddler的工具是Fiddler

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM