[c#] Windows.Web.Http.HttpClient#基本認証で無効な資格情報が使用された場合、GetAsyncは不完全な例外をスローします。



Answers

AllowUI HttpBaseProtocolFilterfalse設定すると、このエラーは停止します。

ダイアログボックスを表示し、ユーザーが資格情報を入力できるようにするには、UIスレッドでWebリクエストを開始する必要があります。

Question

私はAPI呼び出しを行うWindowsランタイムコンポーネントに取り組んでいます。 今日まで私はSystem.Net HttpClientと関連モデルを使用しましたが、代わりにWinRTストリームを活用するためにWindows.Webに切り替えました。

usingステートメントを変更すること、 HttpContentIHttpContentに交換すること、 WindowsRuntimeExtensionsを使用してIInputStreamをJSON.NET用のStreamに変更することなど、私は特別なことをする必要はありませんでした。 しかし、突然、私の16回のテストのうち3回は失敗しましたが、以前はすべてが機能しました。

すべての3(統合)テストでは、無効な資格情報でログインしたときにエラー応答を受け取ることが検証されます。 ログインも含めて(ただし有効な資格情報を使って)他のテストがあり、うまく動作します。 与えられたエラーメッセージはAggregateException型であり、メッセージとして持っています

System.AggregateException :1つ以上のエラーが発生しました。 ---> System.Exception :要素が見つかりません。

親ウィンドウのハンドルが設定されていないため、ダイアログを表示できません。

例外にはHRESULT値が含まれます。 outerexceptionは値-2146233088-2146233088に対応し、innerexceptionは-2147023728-2147023728に対応し0x80070490 。 どちらもMSDNページの既知のエラーコードではありません。

調査後:

スタックトレース:

Result StackTrace:  
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at xx.Models.Requests.GetRequest.<ExecuteRequestAsync>d__0.MoveNext() in c:\Users\jeroen\Github\Windows-app\xx\xx\Models\Requests\Request.cs:line 17

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at xx.ApiDispatcher.<ExecuteAsync>d__0`2.MoveNext() in c:\Users\jeroen\Github\Windows-app\xx\xx\ApiDispatcher.cs:line 40

 --- End of inner exception stack trace ---

    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at xx.ApiDispatcher.Execute[TCallResult,TResponseObject](ApiCall`2 call) in c:\Users\jeroen\Github\Windows-app\xx\xx\ApiDispatcher.cs:line 22

もともと私の質問は、実際の問題が隠されているように思われたため、やや異なっていました。 私は、 HttpClientよるGET要求が、呼び出しの結果を待つ代わりに(そしてメソッドの残りの部分を実行する)呼び出し元に返されることを発見しました。

私のプロジェクトでは、 var data = await myHttpClient.GetAsync(url); GetAsync()呼び出しの後に来る次の行は単純に実行されません。

戻ってこないようにするために.ConfigureAwait(false)を追加しても違いはありません。

ユーザーが無効な資格情報でログインしようとすると、 AggregateExceptionがスローされます。 何らかの理由で、 HttpClientが例外をスローすることにしました。私は使用できるリターン値を与えませんでした。 ここでの問題は、 COMExceptionTaskCanceledExceptionAggregateExceptionExceptionキャッチすることは後者をトリガするだけで、どのような例外が発生するのかはCOMExceptionません。

私は、非同期統合テストがマルチスレッドのMSTest環境ではうまく動作しないことも知ったので、私が持っていたいくつかの失敗したテストについて説明します。

また、私は最終的に、問題を示す例を持っています(しかし、私は基本的な認証を取るWebサービスを提供することはできません)!

[TestMethod]
public void TestMethod3()
{
    Assert.IsTrue(new Test().Do().AsTask().Result);
}

public sealed class Test
{
   public IAsyncOperation<bool> Do()
   {
       return DoSomething().AsAsyncOperation();
   } 

   private async Task<bool> DoSomething()
   {
       var client = new HttpClient();
       var info = "jeroen.vannevel@something.com:nopass";
       var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(info));
       client.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Basic", token);

       var data = await client.GetAsync(new Uri("https://mytestdomain/v2/apikey?format=Json"));
       return true;
   }
}

このコードを有効なパスワードで実行すると、無効なパスワードがAggregateExceptionをスローする間はtrueが返されtrue

今私はGetAsync()呼び出しの周りに一般ExceptionExceptionキャッチすることで問題を回避していますが、これは非常に初歩的なので、この不完全な例外が最初にスローされる理由を知りたいと思います。




Related