Reputation: 71
I wrote this simple call on a XAML app to try to call a REST service.
The program seems work but I have issues with async methods... I see on fiddler that I receive the token but the program didn't notice..
How can I fix it? Are there best practices to do that?
This is the code behind of the file xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Newtonsoft.Json.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
namespace CallRESTToken
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
try
{
const string userName = "user";
const string password = "password";
const string apiBaseUri = "http://example.com";
const string apiGetPeoplePath = "/api/values";
//Get the token
var token = GetAPIToken(userName, password, apiBaseUri).Result;
textBoxtoken.Text = (token);
//Console.WriteLine("Token: {0}", token);
//Make the call
var response = GetRequest(token, apiBaseUri, apiGetPeoplePath).Result;
textBox1view.Text = (response);
//Console.WriteLine("response: {0}", response);
//wait for key press to exit
//Console.ReadKey();
}
catch (Exception ex)
{
throw ex;
}
}
private static async Task<string> GetAPIToken(string userName, string password, string apiBaseUri)
{
try
{
using (var client = new HttpClient())
{
//setup client
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//setup login data
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", userName),
new KeyValuePair<string, string>("password", password),
});
//send request
HttpResponseMessage responseMessage = await client.PostAsync("/token", formContent);
//get access token from response body
var responseJson = await responseMessage.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseJson);
return jObject.GetValue("access_token").ToString();
}
}
catch (Exception ex)
{
throw ex;
}
}
static async Task<string> GetRequest(string token, string apiBaseUri, string requestPath)
{
try
{
using (var client = new HttpClient())
{
//setup client
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
//make request
HttpResponseMessage response = await client.GetAsync(requestPath);
var responseString = await response.Content.ReadAsStringAsync();
return responseString;
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
Upvotes: 2
Views: 685
Reputation: 247451
You are mixing async
with .Result
blocking calls.
Update event handler to use async/await and remove .Result
blocking calls. Event handlers are the exempted case that allows async void
private async void button_Click(object sender, RoutedEventArgs e) {
try {
//... code removed for brevity
//Get the token
var token = await GetAPIToken(userName, password, apiBaseUri);
//... code removed for brevity
//Make the call
var response = await GetRequest(token, apiBaseUri, apiGetPeoplePath);
//... code removed for brevity
} catch (Exception ex) {
throw ex;
}
}
Read up Async/Await - Best Practices in Asynchronous Programming
Upvotes: 2