0

承認されていない場合は、カスタム HttpClientHandler を使用してテストを承認します。Windows ストア ユニット テスト アプリのプロジェクト タイプが使用されます

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); 

実行されるのは 2 回目です。

誰かがなぜそれが起こったのか説明できますか? リクエストがキャンセルされるのはなぜですか?

4

1 に答える 1

0

実際に応答を受け取った後に要求にヘッダーを追加しようとしています (既に待機しているためSendAsync) 論理的に不可能であり、元の要求がキャンセルされます。

于 2013-09-10T12:48:11.533 に答える