【发布时间】:2015-03-20 12:56:26
【问题描述】:
我正在开发我的第一个 Windows Phone 8.1 应用程序(如果这很重要,则通用,但目前只有 Windows Phone 实现)。起初一切都非常顺利,但是一旦我的应用程序运行了大约 25-30 分钟,我就不能再使用我的HttpClient。我使用Windows.Web.Http.HttpClient。
在我第一次尝试s I used a singleHttpClientand reused it all the time. As I became aware that this is not working I started using a newHttpClient` 时为每个请求。但还是没有运气。
这是我获取新HttpClient的方法:
private HttpClient GetClient()
{
var filter = new HttpBaseProtocolFilter
{
AllowUI = false,
CacheControl = { WriteBehavior = HttpCacheWriteBehavior.NoCache },
ServerCredential =
new PasswordCredential(
BaseApiUri.ToString(),
credentials.UserName,
credentials.Password),
};
var httpClient = new HttpClient(filter);
var headers = httpClient.DefaultRequestHeaders;
var httpConnectionOptionHeaderValueCollection = headers.Connection;
httpConnectionOptionHeaderValueCollection.Clear();
headers.Accept.TryParseAdd("application/json");
headers.CacheControl.TryParseAdd("no-cache");
headers.Add("Pragma", "no-cache");
headers.Add("Keep-Alive", "false");
headers.Cookie.Clear();
return httpClient;
}
设置标头和清除 cookie 的额外代码是我试图阻止可能发生的某种连接缓存的尝试。但还是没有运气。
我的 API 请求方法如下:
private async Task<bool> PostNoResponseRequestTo(string relativeUri, object requestContent, CancellationToken cancellationToken)
{
var targetUri = new Uri(BaseApiUri, relativeUri);
var requestJson = JsonConvert.SerializeObject(requestContent);
var content = new HttpStringContent(requestJson, UnicodeEncoding.Utf8, "application/json");
try
{
using (var httpClient = this.GetClient())
{
var post =
await httpClient.PostAsync(targetUri, content).AsTask(cancellationToken).ContinueWith(
async request =>
{
using (var response = await request)
{
return response.IsSuccessStatusCode;
}
},
cancellationToken);
return await post;
}
}
catch (Exception)
{
return false;
}
}
这可以正常工作大约 25-30 分钟,之后对 api 的调用突然开始失败。我开始收到401,但正如您所见,我已经指定了凭据,并且因为这些凭据正在工作并且不会更改(硬编码它们以对此进行测试),我开始相信问题出在 API 方面。
这是我得到的回复:
StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 2, Content: Windows.Web.Http.HttpStreamContent, Headers:
{
Server: Microsoft-IIS/8.5
Date: Fri, 20 Mar 2015 14:25:06 GMT
WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+NounceRemoved",charset=utf-8,realm="Digest", Negotiate, NTLM
X-Powered-By: ASP.NET
}
{
Content-Length: 1344
Content-Type: text/html
}
我的 API 由一个带有 ServiceStack 的 Asp.Net 项目组成,以实现其 API 功能。 这是在具有激活摘要身份验证的 IIS 上运行的(所有其他都被禁用)。
通过检查日志,我发现每次成功调用之前都有一个失败的 API 调用。但是,如果我是对的,这是摘要式身份验证的设计,因为我还没有找到一种方法来告诉客户端对方正在使用摘要式身份验证。我能够在我的其他 .Net 项目中指定此类信息,但由于某种原因,Microsoft 更改了 HttpClient 的代码(和命名空间)。我也知道原始命名空间中的HttpClient 可以通过 nuget 获得,但这对我不起作用,因为我一拨打任何电话就会在输出窗口中收到错误消息。这会在没有任何信息的情况下关闭我的应用程序。
回到日志,我能够在扩展日志记录和分析它们的工具的帮助下获得一些信息。错误类似于(现在无法访问它,稍后将对其进行编辑):'Invalid token passing to function/method'.
我真的希望有人可以帮助我解决这个问题,因为它使应用程序几乎无法使用。我的用户必须每 15 分钟重新启动一次应用才能进入保存站点。
感谢所有对我有帮助的建议。
【问题讨论】:
-
您设法解决了这个问题吗?我现在有同样的问题(在 UWP 中)。整整 10 分钟后,我只得到 401 作为响应...
-
@Dust258 不,抱歉,我们使用的是工作区。我们只是多次尝试身份验证,这对我们有用。
标签: c# iis windows-phone-8.1 servicestack digest-authentication