Another quick video tutorial from me. Here, we will focus on implementing our own “SDK” responsible for handling the Facebook Graph API using C# and .NET Core (of course you can achieve the same result on the full .NET platform).





If you’re just like me targeting the .NET Core, most likely you realized that Facebook SDK for .NET is not really being supported, at least currently, based on the latest date of the master branch update. And of course the same does apply to the NuGet packages.

Thus, we’re kinda on our own, however, it turns out that accessing the Graph API is quite easy. All we need to do is to make use of the HttpClient or any other type that is responsible for handling the HTTP requests. Let’s jump right into the code:

public class Account { public string Id { get; set; } public string Name { get; set; } public string Email { get; set; } public string Locale { get; set; } public string UserName { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Gender { get; set; } } 1 2 3 4 5 6 7 8 9 10 11 public class Account { public string Id { get ; set ; } public string Name { get ; set ; } public string Email { get ; set ; } public string Locale { get ; set ; } public string UserName { get ; set ; } public string FirstName { get ; set ; } public string LastName { get ; set ; } public string Gender { get ; set ; } }

The Account basically represents the user account in the Facebook. Please note that you may include there as many more properties as you wish.

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"); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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" ) ; } }

The FacebookClient is responsible for handling the POST and GET requests to the Facebook API. Quite straightforward code, no magic here, just keep in mind to add a reference to the Newtonsoft.Json package.

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,email,first_name,last_name,age_range,birthday,gender,locale"); if (result == null) { return new Account(); } var account = new Account { Id = result.id, Email = result.email, Name = result.name, UserName = result.username, FirstName = result.first_name, LastName = result.last_name, Locale = result.locale }; return account; } public async Task PostOnWallAsync(string accessToken, string message) => await _facebookClient.PostAsync(accessToken, "me/feed", new {message}); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 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,email,first_name,last_name,age_range,birthday,gender,locale" ) ; if ( result == null ) { return new Account ( ) ; } var account = new Account { Id = result . id , Email = result . email , Name = result . name , UserName = result . username , FirstName = result . first_name , LastName = result . last_name , Locale = result . locale } ; return account ; } public async Task PostOnWallAsync ( string accessToken , string message ) = > await _facebookClient . PostAsync ( accessToken , "me/feed" , new { message } ) ; }

Our FacebookService is where the true “business logic” lays in. It does make use of the underlying FacebookClient in order to execute the HTTP requests to the specified endpoints using some additional arguments.

public class Program { public static void Main(string[] args) { var accessToken = "YOUR_GRAPH_API_ACCESS_TOKEN"; var facebookClient = new FacebookClient(); var facebookService = new FacebookService(facebookClient); var getAccountTask = facebookService.GetAccountAsync(accessToken); Task.WaitAll(getAccountTask); var account = getAccountTask.Result; Console.WriteLine($"{account.Id} {account.Name}"); var postOnWallTask = facebookService.PostOnWallAsync(accessToken, "Hello from C# .NET Core!"); Task.WaitAll(postOnWallTask); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Program { public static void Main ( string [ ] args ) { var accessToken = "YOUR_GRAPH_API_ACCESS_TOKEN" ; var facebookClient = new FacebookClient ( ) ; var facebookService = new FacebookService ( facebookClient ) ; var getAccountTask = facebookService . GetAccountAsync ( accessToken ) ; Task . WaitAll ( getAccountTask ) ; var account = getAccountTask . Result ; Console . WriteLine ( $ "{account.Id} {account.Name}" ) ; var postOnWallTask = facebookService . PostOnWallAsync ( accessToken , "Hello from C# .NET Core!" ) ; Task . WaitAll ( postOnWallTask ) ; } }

And finally, our actual application makes use of the FacebookService in order to get our Facebook account and post a message onto our wall. Just remember to get your access token here and mark the needed permissions. And as you may have already noticed, it’s a trivial console application, therefore the Task.WaitAll() is being invoked.

It wasn’t that difficult after all, was it? You can download the source code of this sample application by clicking here.