48915

GetAsync azure call no result

Question:

Using VS 2017 Community. Azure.

I have Azure setup, I have a blank webapp created just for test purpose.

My actual site is an Angular2 MVC5 site, currently run locally.

The following is the code that should... Contact azure providing secret key(the site is registered in azure Active directory). From this i get a token i then can use to contact azure api and get list of sites.

WARNING: code is all Sausage code/prototype.

<strong>Controller</strong>

public ActionResult Index() { try { MainAsync().ConfigureAwait(false); } catch (Exception e) { Console.WriteLine(e.GetBaseException().Message); } return View(); } static async System.Threading.Tasks.Task MainAsync() { string tenantId = ConfigurationManager.AppSettings["AzureTenantId"]; string clientId = ConfigurationManager.AppSettings["AzureClientId"]; string clientSecret = ConfigurationManager.AppSettings["AzureClientSecret"]; string token = await AuthenticationHelpers.AcquireTokenBySPN(tenantId, clientId, clientSecret).ConfigureAwait(false); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); client.BaseAddress = new Uri("https://management.azure.com/"); await MakeARMRequests(client); } } static async System.Threading.Tasks.Task MakeARMRequests(HttpClient client) { const string ResourceGroup = "ProtoTSresGrp1"; // Create the resource group // List the Web Apps and their host names using (var response = await client.GetAsync( $"/subscriptions/{Subscription}/resourceGroups/{ResourceGroup}/providers/Microsoft.Web/sites?api-version=2015-08-01")) { response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false); foreach (var app in json.value) { Console.WriteLine(app.name); foreach (var hostname in app.properties.enabledHostNames) { Console.WriteLine(" " + hostname); } } } }

Controller class uses a <strong>static helper class</strong> that gets the token from Azure...

public static class AuthenticationHelpers { const string ARMResource = "https://management.core.windows.net/"; const string TokenEndpoint = "https://login.windows.net/{0}/oauth2/token"; const string SPNPayload = "resource={0}&client_id={1}&grant_type=client_credentials&client_secret={2}"; public static async Task<string> AcquireTokenBySPN(string tenantId, string clientId, string clientSecret) { var payload = String.Format(SPNPayload, WebUtility.UrlEncode(ARMResource), WebUtility.UrlEncode(clientId), WebUtility.UrlEncode(clientSecret)); var body = await HttpPost(tenantId, payload).ConfigureAwait(false); return body.access_token; } static async Task<dynamic> HttpPost(string tenantId, string payload) { using (var client = new HttpClient()) { var address = String.Format(TokenEndpoint, tenantId); var content = new StringContent(payload, Encoding.UTF8, "application/x-www-form-urlencoded"); using (var response = await client.PostAsync(address, content).ConfigureAwait(false)) { if (!response.IsSuccessStatusCode) { Console.WriteLine("Status: {0}", response.StatusCode); Console.WriteLine("Content: {0}", await response.Content.ReadAsStringAsync()); } response.EnsureSuccessStatusCode(); return await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false); } } } }

<strong>ISSUE:</strong> Ok so the issue I was faced with was Async Deadlocks in my code. So i looked at this stack post <a href="https://stackoverflow.com/questions/10343632/httpclient-getasync-never-returns-when-using-await-async/10351400#10351400" rel="nofollow">stack post here</a>

I fixed the issues by putting in .ConfigureAwait(false) on most of the await declarations.

Code runs and gets all the way back to the controller with a token etc and runs through the MakeARMRequests(HttpClient client) method, however the json only returns 1 result "{[]}" when i debug and as such ignores the loops.

My question is, is my code the culprit here? or would this point to a configuration setting in azure?

Answer1:

Not sure if this is the issue you are facing now BUT you never wait for a result from your async action in the first method Index in your code. MainAsync().ConfigureAwait(false); will immediately return and continue to the next block while the task MainAsync() will start in the background. The catch handler also does nothing because you dont wait f or a result.

Option 1 (recommended)

public async Task<ActionResult> Index() { try { await MainAsync().ConfigureAwait(false); } catch (Exception e) { Console.WriteLine(e.GetBaseException().Message); } return View(); }

Option 2 if you can't use async/await for some reason

public ActionResult Index() { try { MainAsync().GetAwaiter().GetResult(); } catch (Exception e) { Console.WriteLine(e.GetBaseException().Message); } return View(); }

Answer2:

The Code looks OK and runs fine, Anyone who could help verify would be good, but one can assume this is OK. The issue for this was configuration in azure, When you register an app you must set a certain number of Access controls via the subscription.

In this case I set some more specific things for the web api , for now set the app as owner and made reference to service management api.

Probably don't need half the "IAM" added in the subscription to the registered app, I simply went through adding the relevant ones and debugging each time until finally i got the results expected.

Recommend

  • BaasBox and C# from WP8?
  • How to call Web API (App Service) remotely
  • How to stream zip file from TFS api
  • Httpclient consume web api via console app C#
  • Using SFAuthenticationSession to log in user to Microsoft Graph
  • Spring MVC AccessDeniedException 500 error received instead of custom 401 error for @PreAuthorized u
  • Process.StartTime Access Denied
  • PHP exec response as string?
  • Giving security priviliege to a scheduler in Java EE 6
  • Youtube upload API and cordova / phonegap
  • Sails.js API passport.js authentication
  • Uber API - requests endpoint cannot read read json
  • Command line installation of Code Signing certificates, .p12 files, and mobileprovisions
  • Eclipse MTJ doesn't see Java ME SDK 3.0 devices
  • Android Google Maps API v2 start navigation
  • System.InvalidCastException: Specified cast is not valid
  • Dialing with Intent.ACTION_CALL stopps at # in phone number
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • Read text file and split every line in MSBuild
  • req.body is undefined - nodejs
  • RectangularRangeIndicator format like triangular using dojo
  • Counter field in MS Access, how to generate?
  • Get object from AWS S3 as a stream
  • How to recover from a Spring Social ExpiredAuthorizationException
  • Java applet as stand-alone Windows application?
  • Cross-Platform Protobuf Serialization
  • MySQL WHERE-condition in procedure ignored
  • Adding custom controls to a full screen movie
  • SetUp method failed while running tests from teamcity
  • Comma separated Values
  • Revoking OAuth Access Token Results in 404 Not Found
  • Error creating VM instance in Google Compute Engine
  • Hits per day in Google Big Query
  • Angular 2 constructor injection vs direct access
  • how does django model after text[] in postgresql [duplicate]
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • File not found error Google Drive API
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • UserPrincipal.Current returns apppool on IIS