为HttpClientRequestMessage添加标头后的原因CancellationToken.IsCancellationRequested更改为true

时间:2013-09-09 21:59:54

标签: httpclient cancellation-token

如果未经授权,我使用自定义HttpClientHandler来授权测试。 使用Windows Store Unit Test App项目类型

using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Security.Credentials;
using Windows.UI.Popups;
using XperiAndri.Efficiency.Common.Http.Handlers;

namespace XperiAndri.Efficiency.Common.Tests.Online
{
    public class AuthenticationHandler : DelegatingHandler
    {
        private const string user = "";
        private const string password = "";
        private const string MobileServiceAuthenticationTokenHeader = "X-ZUMO-AUTH";

        private readonly PasswordVault vault = new PasswordVault();

        public IMobileServiceClient Client { get; set; }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                var headers = request.Headers;

                PasswordCredential credential = FindCredential();
                if (credential != null)
                {
                    Client.CurrentUser = new MobileServiceUser(user) { MobileServiceAuthenticationToken = credential.Password };
                    headers.Remove(MobileServiceAuthenticationTokenHeader);
                    credential.RetrievePassword();
                    headers.Add(MobileServiceAuthenticationTokenHeader, credential.Password);
                    response = await base.SendAsync(request, cancellationToken);
                }

                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    JObject content = new JObject { { "user", user }, { "password", password } };
                    var result = await Client.InvokeApiAsync("UnitTestLogin", content, HttpMethod.Post, null);
                    string token = result["token"].Value<string>();
                    if (Client.CurrentUser != null)
                        Client.CurrentUser.MobileServiceAuthenticationToken = token;
                    else
                        Client.CurrentUser = new MobileServiceUser(user) { MobileServiceAuthenticationToken = token };
                    headers.Remove(MobileServiceAuthenticationTokenHeader);
                    headers.Add(MobileServiceAuthenticationTokenHeader, token); // After execution of this line cancellationToken.IsCancellationRequested changes to true
                    // try again!
                    response = await base.SendAsync(request, cancellationToken);
                    if (response.StatusCode != HttpStatusCode.Unauthorized)
                    {
                        if (credential != null)
                            credential.Password = token;
                        else
                        {
                            credential = new PasswordCredential(Client.ApplicationUri.ToString(), user, token);
                            vault.Add(credential);
                        }
                    }
                }
            }

            return response;
        }

        private PasswordCredential FindCredential()
        {
            try
            {
                return vault.FindAllByResource(Client.ApplicationUri.ToString()).FirstOrDefault();
            }
            catch
            {
                return null;
            }
        }

    }
}

查看

行的评论
headers.Add(MobileServiceAuthenticationTokenHeader, token); 

第二次执行。

有人可以解释为什么会这样吗?为什么请求被取消?

1 个答案:

答案 0 :(得分:0)

您尝试在实际接收响应后添加标头(因为您已等待SendAsync),这在逻辑上是不可能的,并导致取消原始请求。