De Windows.Web.Http.HttpClient#GetAsync jette un incomplètes exception lorsque les informations d'identification non valides sont utilisés avec l'authentification de base

Je suis en train de travailler sur un Composant Windows Runtime qui effectue des appels d'API. Jusqu'à ce que plus tôt aujourd'hui, j'ai utilisé le HttpClient et de modèles connexes de System.Net mais basculé Windows.Web au lieu de tirer parti de la WinRT ruisseaux.

Mis à part de changer la using états, par l'échange d' HttpContent à IHttpContent et à l'aide de la WindowsRuntimeExtensions changer mon IInputStream à Stream pour JSON.NET je n'ai pas eu à faire quelque chose de spécial. Cependant soudainement, 3 de mes 16 tests échouent, alors qu'auparavant tout fonctionnait.

Tous les 3 (intégration) des tests de valider que je reçois une réponse d'erreur lors de la connexion avec les informations d'identification non valides. Il y a d'autres tests comprennent l'exploitation forestière en tant que bien (mais avec des informations d'identification valides) et ils fonctionnent très bien. Le message d'erreur donné est de type AggregateException et a comme message

System.AggregateException: Une ou plusieurs erreurs se sont produites. ---> System.Exception: Élément introuvable.

Une boîte de dialogue ne peut pas être affichée car le handle de fenêtre parent n'a pas été définie.

L'exception contient des valeurs HRESULT. Le outerexception a de la valeur -2146233088 qui correspond à 0x80131500 tandis que le innerexception a -2147023728 qui correspond à 0x80070490. Ni de ceux qui sont connus code d'erreur sur la page MSDN.

La suite d'une enquête:

Stacktrace:

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

À l'origine de ma question a été formulée de manière quelque peu différente, car le problème semble être caché. J'ai trouvé que la demande d'OBTENIR par la HttpClient renvoie à l'appelant au lieu d'attendre le résultat de l'appel (et d'exécuter le reste de la méthode).

Dans mon projet, l'exécution de la ligne de var data = await myHttpClient.GetAsync(url); sera de retour à l'appel de la méthode avec un non-objet construit et les lignes suivantes qui viennent après GetAsync() appel sont tout simplement pas exécuté.

Ajoutant .ConfigureAwait(false) de l'empêcher de se retourner ne pas faire une différence.

La AggregateException est levée lorsqu'un utilisateur essaie de se connecter avec des informations d'identification non valides. Pour une raison quelconque, le HttpClient décide de lancer une exception puis, sans me donner un retour de la valeur que je pourrais utiliser. Le problème ici est qu'il ne me dise pas quel type d'exception: la capture de COMException, TaskCanceledException, AggregateException et Exception de déclencher le dernier.

J'ai aussi trouvé que les tests d'intégration ne fonctionne pas bien avec le multithread MSTest de l'environnement, de sorte que explique plusieurs autres tests ne que j'ai eu (mais a très bien fonctionné individuellement)

Moi aussi, enfin, un exemple qui illustre le problème (mais je ne peux pas fournir un service web qui prend basic auth)!

[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 = "[email protected]: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;
   }
}

L'exécution de ce code avec un mot de passe valide sera de retour true alors qu'un mot de passe invalide va jeter un AggregateException.

Droit maintenant, je suis en train de contourner le problème en attrapant un général Exception autour de l'appel à GetAsync() mais c'est très rudimentaire et j'aimerais savoir pourquoi ce incomplète exception est levée dans la première place.

  • Pourriez-vous essayer de définir des informations d'authentification différentes: client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", token);
  • c'est une partie de la System.Net.Http espace de noms et ne sont pas compatibles avec la Windows.Web.Http.HttpClient à moins que je sois donnant sur quelque chose.
  • À droite, vous êtes à l'aide de Windows.Web. Mon erreur.
  • Avez-vous essayé de créer un HttpHandler et les paramètres de son Credentials propriété, ensuite le passant à HttpClient? var client = new HttpClient(handler)
  • c'est System.Net ainsi.
  • Désolé, je ment un IHttpFilter: msdn.microsoft.com/en-us/library/windows/apps/...
  • J'ai fait un IHttpFilter mais je ne vois pas comment il peut faire une différence: il passe sur les informations à l'éventuel GetAsync méthode; il n'a tout simplement dans une étape ultérieure. Configuration des informations d'identification dans le filtre n'a pas changé le résultat.
  • Je pense que je l'ai cette fois 🙂
  • Le cas échéant, ajoutant simplement "Pragma:no-cache" à ma demande d'en-tête résolu ce problème pour moi.