Manspof
Manspof

Reputation: 357

Accessing Facebook API using C# await and stuck forever

I'm trying to implement Facebook login and get data in c# project. what I'm trying to do is that user press his firstname and password then he press on the login button and login then it return his data. the when I press on the button the program is freeze.

that's my project implementation

Account.cs

 public class Account
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Birthday { get; set; }
}

Facebook.client

public interface IFacebookClient
{
    Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null);
    Task PostAsync(string accessToken, string endpoint, object data, string args = null);
}

public class FacebookClient : IFacebookClient
{
    private readonly HttpClient _httpClient;

    public FacebookClient()
    {
        _httpClient = new HttpClient
        {
            BaseAddress = new Uri("https://graph.facebook.com/v2.8/")
        };
        _httpClient.DefaultRequestHeaders
            .Accept
            .Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null)
    {
        var response = await _httpClient.GetAsync($"{endpoint}?access_token={accessToken}&{args}");
        if (!response.IsSuccessStatusCode)
            return default(T);

        var result = await response.Content.ReadAsStringAsync();

        return JsonConvert.DeserializeObject<T>(result);
    }

    public async Task PostAsync(string accessToken, string endpoint, object data, string args = null)
    {
        var payload = GetPayload(data);
        await _httpClient.PostAsync($"{endpoint}?access_token={accessToken}&{args}", payload);
    }

    private static StringContent GetPayload(object data)
    {
        var json = JsonConvert.SerializeObject(data);

        return new StringContent(json, Encoding.UTF8, "application/json");
    }
}

FacebookService.cs

public interface IFacebookService
{
    Task<Account> GetAccountAsync(string accessToken);
    Task PostOnWallAsync(string accessToken, string message);
}

public class FacebookService : IFacebookService
{
    private readonly IFacebookClient _facebookClient;

    public FacebookService(IFacebookClient facebookClient)
    {
        _facebookClient = facebookClient;
    }

    public async Task<Account> GetAccountAsync(string accessToken)
    {
        var result = await _facebookClient.GetAsync<dynamic>(
            accessToken, "me", "fields=id,name,birthday,email");

        if (result == null)
        {
            return new Account();
        }

        var account = new Account
        {
            Id = result.id,
            Email = result.email,
            Name = result.name,
            Birthday = result.Birthday
        };

        return account;
    }
    public async Task PostOnWallAsync(string accessToken, string message)
        => await _facebookClient.PostAsync(accessToken, "me/feed", new {message});
}  

FacebookSettings.cs

var facebookClient = new FacebookClient();
        var facebookService = new FacebookService(facebookClient);
        var getAccountTask = facebookService.GetAccountAsync(FacebookSettings.AccessToken);
        Task.WaitAll(getAccountTask);
        var account = getAccountTask.Result;
        Console.WriteLine($"{account.Id} {account.Name}");

Login form button

private void btn_facebook_Click(object sender, EventArgs e)
    {
        var facebookClient = new FacebookClient();
        var facebookService = new FacebookService(facebookClient);
        var getAccountTask = facebookService.GetAccountAsync(FacebookSettings.AccessToken);
        Task.WaitAll(getAccountTask);
        var account = getAccountTask.Result;
        //Console.WriteLine($"{account.Id} {account.Name}");
    }

it stuck on this line on the await

 public async Task<Account> GetAccountAsync(string accessToken)
    {
        var result = await _facebookClient.GetAsync<dynamic>(accessToken, "me", "fields=id,name,birthday,email");

        if (result == null)
        {
            return new Account();
        }

        var account = new Account
        {
            Id = result.id,
            Email = result.email,
            Name = result.name,
            Birthday = result.Birthday
        };

        return account;
    }

in this line

            var result = await _facebookClient.GetAsync<dynamic>(accessToken, "me", "fields=id,name,birthday,email");

Upvotes: 0

Views: 452

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457057

Here's your problem:

Task.WaitAll(getAccountTask);

Don't block on async code. Use await instead:

private async void btn_facebook_Click(object sender, EventArgs e)
{
  var facebookClient = new FacebookClient();
  var facebookService = new FacebookService(facebookClient);
  var account = await facebookService.GetAccountAsync(FacebookSettings.AccessToken);
}

Upvotes: 1

Related Questions