我有以下方法,它基本上使用他们的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
发送一条消息,指出该流不可读。有了这条线,它告诉我,我无法操纵已经关闭的流。这条小溪是怎么关闭的?为什么我不能从中读取?
答案 0 :(得分: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;
}
答案 1 :(得分:3)
看起来您正在使用DotNetOpenAuth。不幸的是,我认为这个库在将它包装在你的代码收到的ProtocolException之前关闭了WebException的响应流。您可以在DEBUG级别enable logging将响应转储到日志文件中,但我认为您无法通过代码访问它。
其中一个DotNetOpenAuth开发人员描述了情况here:
DotNetOpenAuth在处理和抛出包装的异常时关闭HTTP响应流,因为如果DNOA没有关闭流,您的开放流分配将填满,然后您的应用将开始挂起。如果我没记错的话,DNOA会将响应流的内容写入其日志。
最新(未发布)的DNOA(5.0)版本可能已发生变化,因为当前版本中导致问题的部分代码已被删除。
答案 2 :(得分:0)
WebException可能有不同的原因,并且服务器并不总是需要在某些(错误)环境下返回一个主体,因此没有response.stream。
首先查看返回的状态代码
另一个可以帮助您调查目标的工具是Fiddler