c# - Windows.Web.Http.HttpClient#GetAsync throws an incomplete exception when invalid credentials are used with basic authentication -
i working on windows runtime component makes api calls. until before today used httpclient
, related models system.net
switched on windows.web
instead leverage winrt streams.
aside changing using
statements, swapping httpcontent
ihttpcontent
, using windowsruntimeextensions
alter iinputstream
stream
json.net, didn't have special. 3 out of 16 tests fail whereas worked.
all 3 (integration) tests validate receive error response when logging in invalid credentials. there other tests include logging in (but valid credentials) , work fine. given error message of type aggregateexception
, has message
system.aggregateexception
: 1 or more errors occurred. ---> system.exception
: element not found.
a dialog cannot displayed because parent window handle has not been set.
the exception contains hresult values. outerexception has value -2146233088
corresponds 0x80131500
while innerexception has -2147023728
corresponds 0x80070490
. neither of known error code on the msdn page.
following investigation:
0x80131500
corresponds to cor_e_exception
0x80070490
corresponds to error_not_found
stacktrace:
result stacktrace: @ system.runtime.compilerservices.taskawaiter.throwfornonsuccess(task task) @ system.runtime.compilerservices.taskawaiter.handlenonsuccessanddebuggernotification(task task) @ system.runtime.compilerservices.taskawaiter`1.getresult() @ 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 previous location exception thrown --- @ system.runtime.compilerservices.taskawaiter.throwfornonsuccess(task task) @ system.runtime.compilerservices.taskawaiter.handlenonsuccessanddebuggernotification(task task) @ system.runtime.compilerservices.taskawaiter`1.getresult() @ 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 --- @ system.threading.tasks.task.throwifexceptional(boolean includetaskcanceledexceptions) @ system.threading.tasks.task`1.getresultcore(boolean waitcompletionnotification) @ system.threading.tasks.task`1.get_result() @ xx.apidispatcher.execute[tcallresult,tresponseobject](apicall`2 call) in c:\users\jeroen\github\windows-app\xx\xx\apidispatcher.cs:line 22
originally question worded differently because actual problem seemed hidden. have found out request httpclient
returns caller instead of awaiting result of phone call (and executing rest of method).
in project, executing line var info = await myhttpclient.getasync(url);
homecoming calling method non-constructed object , subsequent lines come after getasync()
phone call not executed.
adding .configureawait(false)
stop going did not create difference.
the aggregateexception
thrown when user tries login invalid credentials. reason httpclient
decides throw exception without giving me homecoming value use. problem here not tell me kind of exception: catching comexception
, taskcanceledexception
, aggregateexception
, exception
trigger latter.
i have found out asynchronous integration tests not work multithreaded mstest environment, explains several other failed tests had (but worked fine individually)
i also, finally, have illustration demonstrates problem (but can't provide webservice takes basic auth)!
[testmethod] public void testmethod3() { assert.istrue(new test().do().astask().result); } public sealed class test { public iasyncoperation<bool> do() { homecoming 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 info = await client.getasync(new uri("https://mytestdomain/v2/apikey?format=json")); homecoming true; } }
executing code valid password homecoming true
while invalid password throw aggregateexception
.
right working around problem catching general exception
around phone call getasync()
rudimentary , i'd know why incomplete exception thrown in first place.
after reconstructing illustration , playing around, figured out happens.
var info = await client.getasync(new uri("https://mytestdomain/v2/apikey?format=json"));
the getasync
method invokes http request invalid credentials. happens returned request tries window can come in right credentials, doesn't find one. hence throws element not found
while searching window.
this can fixed creating httpbaseprotocolfilter
, setting allowui
property false
, passing httpclient
:
private async task<bool> dosomething() { var httpbasefilter = new httpbaseprotocolfilter { allowui = false }; var client = new httpclient(httpbasefilter); var info = "jeroen.vannevel@something.com:nopass"; var token = convert.tobase64string(encoding.utf8.getbytes(info)); client.defaultrequestheaders.authorization = new httpcredentialsheadervalue("basic", token); var info = await client.getasync(new uri("https://mytestdomain/v2/apikey?format=json")); homecoming true; }
c# .net windows-runtime async-await dotnet-httpclient
No comments:
Post a Comment