2013-03-16 3 views
2

У меня есть следующий метод, который в основном аутентифицирует пользователей со своими учетными данными в Facebook. По какой-то причине я получаю WebException при попытке обработать ключ авторизации (код). Поэтому я попытался прочитать поток ответов, чтобы узнать, что происходит, но я продолжаю получать ошибки при чтении потока. Вот мой код:Чтение потока ответов 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 с сообщением, которое говорит, поток не был читаемым. И с этой строкой на месте, она говорит мне, что я не могу манипулировать потоком, который уже был закрыт. Как этот поток был закрыт? И почему я не могу читать?

ответ

3

Похоже, что вы используете DotNetOpenAuth. К сожалению, я думаю, что эта библиотека закрывает поток ответов в WebException, прежде чем обернуть его в исключение ProtocolException, которое получает ваш код. Вы можете enable logging на уровне DEBUG, чтобы ответ сбрасывался в файл журнала, но я не думаю, что вы найдете какой-либо способ получить к нему доступ из вашего кода.

Один из дэвов DotNetOpenAuth описывает ситуацию here:

DotNetOpenAuth закрывает поток ответа HTTP при обработке и метания обернутого исключения, потому что, если DNOA не закрыть поток, ваши открытых потоки выделение будет заполнить и тогда ваше приложение начнет висит. DNOA записывает содержимое потока ответа в свой журнал, если я правильно помню.

Возможно, в последней (невыпущенной) версии DNOA (5.0) изменения были изменены, поскольку часть кода, вызывающая проблему в текущей версии, была удалена.

0

У WebException могут быть разные причины, и сервер не всегда обязан возвращать тело при определенном (ошибке) обстоятельстве, таким образом, нет response.stream.

Посмотрите на возвращаемое код_состоянии первого

Еще один инструмента, который поможет вам выяснить, что происходит в Fiddler

+0

@Iboshuizen: статус "ProtocolError'. – Kassem

+0

Вы пробовали скрипач, чтобы узнать, какая информация идет от клиента к серверу и обратно? – lboshuizen

5

Вы можете прочитать тело ответа. Я нашел решение в this answer.

Вы должны отливать поток до 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; 
} 
+0

Это один из тех случаев, когда я хотел бы дать более одного взлома. –

Смежные вопросы