Prabir's Blog

open source geek and lover of all tech  

While working on an iOS app I bumped into a situation where I needed to consume a .NET web service on my Windows Virtual Machine hosted on IISExpress. After searching in internet I couldn’t even find one solution that was pleasing to my eyes. Since I was using Nancy Web Framework (the coolest .NET web framework out there), I almost went to even coding in MonoDevelop in Mac as Nancy official supports Mono. But since I like to have my dev environment similar to my production environment I insisted on using a Windows box.

There was even a solution using Powershell (which I think is one of the worst shell on the planet. @GrumpyDev sums it well. I removed some of my replies as it was not related to this context.)

powershell load time

 

First of all you would want to install the Bonjour Print Services for Windows. You can download it from http://support.apple.com/kb/DL999. This will allow you to access your windows machine from mac using computername.local like shown below from mac. (Below is the default full IIS8 homepage.)

 

default IIS8 homepage from mac

 

In my case computer name is pswin8mac.

Screen Shot 2012-09-18 at 7.48.09 PM

 

And then I found this bat script https://gist.github.com/3725469 by Duncan Smart which is as simple as double clicking it in an admin mode. Save this as a “add urlacl.cmd” file name and run it using admin mode. You will then be prompted to enter a port number. Type the port number and press enter.

:: NOTE needs to be elevated

@set /p HTTP_PORT=Enter Port number [e.g. 10082]: 

@rem install http://support.apple.com/kb/DL999 so you can access computername.local from mac

netsh http add urlacl url=http://*:%HTTP_PORT%/ user=everyone
netsh http add urlacl url=http://localhost:%HTTP_PORT%/ user=everyone
netsh http add urlacl url=http://%COMPUTERNAME%:%HTTP_PORT%/ user=everyone
netsh http add urlacl url=http://%COMPUTERNAME%.local:%HTTP_PORT%/ user=everyone
@pause

You will then need to modify the IISExpress applicationhost.config file located at [Documents folder]\IISExpress\config\applicationhost.config and add the binding configuration with your machine name.

Thats it. Happy debugging :)

<site name="WebSite1" id="1" serverAutoStart="true">
    <application path="/">
        <virtualDirectory path="/" physicalPath="C:\PathToWebSite" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation=":10082:localhost" />
        <binding protocol="http" bindingInformation="*:10082:pswin8mac.local" />
    </bindings>
</site>

add urlacl.cmd (470.00 bytes)

A lot has been happening around Facebook C# SDK for a past few months. Earlier this week we official released the v6 RTW of SDK and today I am extremely excited to announce that Facebook C# SDK is now part of the Outercurve Foundation. You care read more about it at http://www.outercurve.org/News/articleType/ArticleView/articleId/54/Outercurve-Foundation-Accepts-Facebook-C-SDK-Project

Overtime Facebook C# SDK has gone over numerous internal architectural changes that allowed us to easily target wide variety of platforms. Currently we support .NET 3.5 Client Profile, .NET 4.0 Client Profile, Silverlight 5 and Windows Phone 7.1 (Mango) and even .NET 4.5 (VS11 Beta) and Windows 8 Metro Style Applications (Windows 8 Consumer Preview). This has all been possible due to internal sub-projects that SDK uses which most of you might not even know it existed.

Untitled

Facebook C# SDK consists of another 3 projects bundled in one Facebook.dll.

  1. HttpHelper – (formally known as FluentHttp.Core)
  2. SimpleJson
  3. ReflectionUtils

HttpHelper  is a mockable HTTP helper for .NET 2.0+/SL4+/WP7/WinRT with support for Task Parallel Library as well as async and await in platforms where available.  HttpHelper has allowed us to easily use our existing codes to port it easily to multiple .NET platforms. Here is a simple synchronous example of complex Twitter Streaming Api with HttpHelper and SimpleJson demonstrating how easy it is to use.

private static void StartTwitterStreamingApiSync()
{
    var httpHelper = new HttpHelper("http://stream.twitter.com/1/statuses/sample.json");
    httpHelper.AuthenticateUsingHttpBasicAuthentication("username", "password");

    using (var responseStream = httpHelper.OpenRead())
    {
        using (var reader = new StreamReader(responseStream))
        {
            while (true)
            {
                dynamic json = SimpleJson.DeserializeObject(reader.ReadLine());
                string text = json.text;
                Console.WriteLine(text);

                Console.WriteLine();
            }
        }
    }
}

And an asynchronous equivalent of the above code using async/await with support for cancellation.

private static async Task StartTwitterStreamingApi(CancellationToken ct)
{
    var httpHelper = new HttpHelper("http://stream.twitter.com/1/statuses/sample.json");
    httpHelper.AuthenticateUsingHttpBasicAuthentication("username", password);

    using (var responseStream = await httpHelper.OpenReadTaskAsync(ct))
    {
        using (var reader = new StreamReader(responseStream))
        {
            while (true)
            {
                dynamic json = SimpleJson.DeserializeObject(await reader.ReadLineAsync());
                string text = json.text;
                Console.WriteLine(text);

                Console.WriteLine();
            }
        }
    }
}

SimpleJson – SimpleJson is the default lightweight json serializer/deserializer for Facebook C# SDK. All of the json parsing and dyanmic that you see in the SDK has been possible due to SimpleJson.

ReflectionUtils – SimpleJson contains another internal helper project called ReflectionUtils which related to all the reflection helper methods.

Dividing Facebook C# SDK into internal sub-project has allowed us to easily target multiple platforms. In fact it was so easy that after porting ReflectionUtils, SimpleJson and HttpHelper to WinRT (Windows 8 Metro Style Application), it took us less then 5 minutes to port the entire Facebook C# SDK to WinRT.  If you are creating applications that target wide variety of .NET platforms, we believe you can take advantage of both Facebook C# SDK and these sub-projects which are also now part of the Outercurve Foundation.

All these project are open source and is available under the Facebook C# SDK Github organization which can be found at https://github.com/facebook-csharp-sdk

This is an update to my old blog post on Writing your First Facebook Application using Facebook C# SDK v5. Due to the popularity of the post which has allowed developers to jump start on using Facebook C# SDK for creating Facebook Application, I have decided to update parts of the samples in order to reflect changes in v6. If you are using v5, I would recommend you to read the original post on Writing your First Facebook Application.

We will start up with a simple WinForms application which will include the authorization process and making requests to the Facebook server. Along the way I will also be explaining some of the Facebook and OAuth terminologies which I think will come as an added bonus if you are writing Facebook applications. (Even though this is a Windows application I highly recommend you to go through this particular tutorial whether you are developing a Facebook web application, Silverlight application or even Windows Phone application or Windows 8 Metro Style Apps.)

So let’s get started.

Getting the Facebook C# SDK binaries:

Starting from v6, we will only be providing compiled binaries via NuGet. (If you are on older versions of Visual Studio or editions where NuGet package manager is not supported, you will need to download the Facebook.dll using the NuGet command line tool.)

Starting from v6 we are dropping FacebookWeb and FacebookWebMvc NuGet packages.

I will be using v6.0.2-alpha in this sample. Since v6 is still at a pre-release stage you will need to pass an extra –Pre  option.

Install-Package Facebook –Pre

Rather then going through all File>New Project, I will rather explain the core features that I have used in the sample to keep this post small before all you start getting bored. You can find the download link of the complete sample at the end of this post.

Summary of the Facebook App:

We will create a simple WinForm C# 4.0 application that contains the login button. When clicked it will ask the user to authorize the application with specified permissions. Once authorized it will display a message box saying “hi …”. We will also display the logout button once the user has logged in.

Authentication:

If you haven’t created a Facebook application you will need to do so at http://www.facebook.com/developers/createapp.php. (This Facebook application is also referred to as client in OAuth 2). For windows app you would require only the application id (also referred to as client id).

Starting from v5 we have migrated all platforms (desktop,web, silverlight and wp7) to use the new Facebook OAuth Dialog. In v5 all the oauth related features are in FacebookOAuthClient. In the process of simplifying v6, we have removed FacebookOAuthClient and moved its features to FacebookClient.

Generating the Login Url:

private Uri GenerateLoginUrl(string appId, string extendedPermissions)
{
    // for .net 3.5
    // var parameters = new Dictionary<string,object>
    // parameters["client_id"] = appId;
    dynamic parameters = new ExpandoObject();
    parameters.client_id = appId;
    parameters.redirect_uri = "https://www.facebook.com/connect/login_success.html";
 
    // The requested response: an access token (token), an authorization code (code), or both (code token).
    parameters.response_type = "token";
 
    // list of additional display modes can be found at http://developers.facebook.com/docs/reference/dialogs/#display
    parameters.display = "popup";
 
    // add the 'scope' parameter only if we have extendedPermissions.
    if (!string.IsNullOrWhiteSpace(extendedPermissions))
        parameters.scope = extendedPermissions;
 
    // generate the login url
    var fb = new FacebookClient();
    return fb.GetLoginUrl(parameters);
}

Whether it is a silverlight or windows phone app or desktop app, this is the unified standard way of generating the login url. (Though you will require to change certain parameters like dispaly=touch for Windows phone to maximize user experience). Unlike v5, no default parameters are set. You will need to manually set all the parameters required for login.

If you are on a .NET Framework where dynamic is not supported, you can use IDictionary<string, object>. Starting from v6 we also support passing anonymous objects instead of IDictionary<string,object>.

var fb = new FacebookClient();
var loginUrl = fb.GetLoginUrl(new { client_id= "...", redirect_uri = "...", .....);

Extended permissions are also known as scope in OAuth 2. You can read more about this at available Facebook permissions at http://developers.facebook.com/docs/authentication/permissions/

By default the display is set to page by Facebook, we overwrite it to popup so that it consumes less space. More information about the display mode can me found at http://developers.facebook.com/docs/reference/dialogs/#display

Response Type is the result given by the Facebook Server on successful authorization. For native windows and windows phone app it is safe to set it as token. But if you are using web applications it is recommend to set it as code because when the Facebook Application redirect after authentication it appends the access_token to the redirect_uri. This means this url along with access token is stored in the browser’s history. (In case you are using a hosted browser control in Windows app, the url is not stored in the browser’s history. So it is safe to use token in desktop apps as compared to websites).

Using the browser user control you would then navigate to the generated login url.

webBrowser.Navigate(loginUrl);

Each time the page changes you would need to listen to it and check if the authorization process is completed.

private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    // whenever the browser navigates to a new url, try parsing the url.
    // the url may be the result of OAuth 2.0 authentication.

    var fb = new FacebookClient();
    FacebookOAuthResult oauthResult;
    if (fb.TryParseOAuthCallbackUrl(e.Url, out oauthResult))
    {
        // The url is the result of OAuth 2.0 authentication
        if (result.IsSuccess)
        {
            var accesstoken = result.AccessToken;
        }
        else
        {
            var errorDescription = result.ErrorDescription;
            var errorReason = result.ErrorReason;
        }
    }
    else
    {
        // The url is NOT the result of OAuth 2.0 authentication.
    }
}

To ease the authentication we can parse the callback url using ParseOAuthCallbackUrl/TryParseOAuthCallbackUrl. TryParseOAuthCallbackUrl returns true if it is recognized as a valid OAuth2 Authentication result. This means even if there was an OAuth 2 error such as user denied, it would still be able to parse it and return true. Thus there is another property called IsSuccess which is set to true if the oauth result was successful in the sense we have the access token or code. Scenario when the IsSuccess is false can be when the user clicks don’t allow. You can then access ErrorDescription and ErrorReason properties to show useful information to the user. So make sure to check it even if TryParse retruns true.

Making requests to Facebook server:

Now that you have the access token you can use that access token to make the request.

If you are using .net 3.5 (or any other platforms that doesn’t support dynamic keyword) then you can the cast it to IDictionary<string, object> and make a request. (If it is an array you can cast it to IList<object>)

var fb = new FacebookClient("access_token");

var result = (IDictionary<string, object>)fb.Get("me");
var name = (string)result["name"];

MessageBox.Show("Hi " + name);

If you are using dynamic you could write it as:

var fb = new FacebookClient("access_token");

dynamic result = fb.Get("me");
var name = result.name;

MessageBox.Show("Hi " + name);

Notice the dynamic keyword in “dynamic result”.

Prior to v6 you also had to use IDictionary<string, object> (or ExpandoObject) to pass parameters as follows.

var parameters = new Dictionary<string,object>();
parameters["fields"] = "id,name,picture";
var result = fb.Get("me", parameters);

Starting from v6 you can use anonymous objects. (IDictionary<string, object> or ExpandoObject will continue to work.)

var result = fb.Get("me", new { fields = new [] { "id", "name", "picture" } });

Note: If you are passing anonymous objects in Windows Phone as parameters, make sure to set [assembly:InternalsVisibleTo("Facebook")]. This is due to the security model of Windows Phone, as anonymous objects are actually a compile generated internal classes.

Logging out:

In order to logout, you will need to generate the logout url using GetLogoutUrl and then navigate to the the generated url.

var fb = new FacebookClient();
var logouUrl = fb.GetLogoutUrl(new { access_token = _accessToken, next = "https://www.facebook.com/connect/login_success.html" });
webBrowser.Navigate(logoutUrl);

Hope this tutorial helps you get started with the Facebook C# SDK. Make sure to checkout this post on making requests to Facebook server. http://blog.prabir.me/post/Facebook-CSharp-SDK-Making-Requests.aspx.

Here is the complete working sample. (make sure you put the appropriate application id before running the sample). I try to update this sample in github with the latest Facebook C# SDK.

https://github.com/prabirshrestha/FB-CSharp-SDK-First-FB-Application (For v5 you can checkout the v5 branch.)

Please ask general questions related to Facebook C# SDK at facebook.stackoverflow.com and tag it with "facebook" or "facebook-c#-sdk". Use comments only to discuss the matter related to this blog post.

The Move

I'm excited to announce that Facebook C# SDK will be moving to a new home at Github (https://github.com/facebook-csharp-sdk/facebook-csharp-sdk) along with SimpleJson (https://github.com/facebook-csharp-sdk/simple-json).

Moving forward we will be using Github for source control and bugs/suggestions (all bugs from codeplex have already been migrated) and Github pages for documentation (https://github.com/facebook-csharp-sdk/facebook-csharp-sdk.github.com). Stackoverflow with tag "facebook-c#-sdk" will be used for asking questions.

NuGet packages will be used as primary distribution for compiled binaries. This means Github downloads will not contain all the releases for compiled binaries but rather the most recent binaries only. Developers using Visual Studio earlier then 2010 or Express Editions will require to use the nuget command line tool.

The Future

With the move to Github we are also announcing a pre-release version of vNEXT (v6.0.1-alpha). A lot has happened in the past few months with introduction to Enhanced OAuth Dialog, Open Graph and ETags to name a few that a time has come for us to rethink how we develop Facebook apps. This has lead us to completely rewrite v6 from scratch.

Tons of features has been added to v6 along with removal of existing features which doesn't make much sense in the present context.

Anonymous Objects as Parameters

One of the most exciting feature to land in v6 is using anonymous object as parameters rather then Dictionary<string,object> or ExpandoObject. (Dictionary and ExpandoObject will continue to work).

var fb = new FacebookClient();
dynamic result = fb.Get("4", new { fields = new[] { "id", "name" } });

GZip/Deflate

GZip/Deflate has been enabled for desktop client profiles (.NET 3.5+). Currently only batch requests returns gzip responses. (https://developers.facebook.com/bugs/235553716524315)

FacebookMediaStream

Rather then converting stream to byte array and using FacebookMediaObject, you can now directly work with FacebookMediaStreams. Stream used in FacebookMediaStream must be manually disposed.

var fb = new FacebookClient(accessToken);
string attachementPath = @"C:\image.jpg";

using (var stream = File.OpenRead(attachementPath))
{
    dynamic result = fb.Post("me/photos",
                                new
                                    {
                                        message = "upload using Facebook C# SDK",
                                        file = new FacebookMediaStream
                                                {
                                                    ContentType = "image/jpg",
                                                    FileName = Path.GetFileName(attachementPath)
                                                }.SetValue(stream)
                                    });
}

ETags

You can now optimize your graph api’s using ETags. For etag you need to pass the special parameter called _etag_

For the first request it should be empty string. _etag_ is specific to Facebook C# SDK.

dynamic result1 = fb.Get("me", new { fields = "id,name", _etag_ = string.Empty});

This will tell the fb c# sdk to return a JsonObject with headers and body.

dynamic headers = result1.headers; // JsonObject of headers.
dynamic body = result1.body; // The actual json response.
// to access the actual json response use result.body.x instead of just result.x
string id = result1.body.id;

Then you can use the etag from the previous response to get the next responses.

dynamic result2 = fb.Get("me", new {fields = "id,name", _etag_ = result1.headers.ETag});
dynamic headers = result1.headers;
// always check if the response has a body.
if(result2.ContainsKey("body")) {
    // we've got the updated response.
    string id = result1.id;
}
else {
    // the last request was the latest.
    // so do nothing.
}

Note: result1.header.ETag (make sure ETag contains the right capitalization). It is exactly how Facebook returns the response header.
when _etag_ is string.Empty it will always return a body, so you don't need to check result1.ContainsKey("body") for it.

ETag support in batch requests

var fb = new FacebookClient(accessToken);

dynamic result = fb.Batch(
    new FacebookBatchParameter("me", new { _etag_ = string.Empty }),
    new FacebookBatchParameter("me", new { _etag_ = "\"ac9e51b60e883e294cc98f35f70a1ec8fdf0e736\"" }),
    new FacebookBatchParameter("me") { Data = new { headers = new Dictionary<string, object> { { "If-None-Match", "\"ac9e51b60e883e294cc98f35f70a1ec8fdf0e736\"" } } } });

Removal of Query/QueryAsync/QueryTaskAsync method

Now that Facebook official supports Fql using graph api, we are removing the Query methods from FacebookClient.

In v6 you can execute Fql query using the following methods.

Single Fql

var result = fb.Get("fql", new { q = "SELECT uid from user where uid=me()" });

MultiQuery Fql:

var resultMulti = fb.Get("fql", new
                                    {
                                        q = new[]
                                                {
                                                    "SELECT uid from user where uid=me()",
                                                    "SELECT name FROM user WHERE uid=me()"
                                                }
                                    });

Named Muliquery:

var resultMultiNamed = fb.Get("fql",
                            new
                                {
                                    q = new
                                    {
                                        id = "SELECT uid from user where uid=me()",
                                        name = "SELECT name FROM user WHERE uid IN (SELECT uid FROM #id)",
                                    }
                                });

Removal of Facebook.Web.dll and Facebook.Web.Mvc.dll

Starting from v6, we are depreciating Facebook.Web.dll and Facebook.Web.Mvc.dll and will no longer be providing it. Over the year we have seen lot of developers using the server side (ASP.NET) as a proxy to Facebook rather then using the Facebook Javascript SDK. We highly encourage users to use both Facebook Javascript SDK and Facebook C# SDK where appropriate. We will continue to support earlier version in v5 branch. Rather then provide Facebook.Web.dll and Facebook.Web.Mvc.dll we will be creating a new repositories in github showing best practices on how to create Facebook apps, Canvas Apps, Windows Phone Apps.

Attributes such as CanvasAuthorize doesn’t make much sense now as the user is now allowed to remove certain permissions and yet grant access to your app when using Enhanced OAuth Dialog. Currently with v5, you will end up with redirect loop incase the user removes the permission.

Since decoding Facebook cookies are not official supported nor documented by Facebook, we are also removing FacebookWebClient. Lot of bug reports in Facebook C# SDK has been based on cookie issues. Starting from v6, you will have to use the Facebook Javascript SDK to get the access token and pass it to the server using secure https connection or use the Facebook OAuth Login Dialog.

Decoding signed request (ParseSignedRequest/TryParseSignedRequest) has been moved to FacebookClient instead.

var fb = new FacebookClient();
dynamic signedRequest = fb.ParseSignedRequest("app_secret", Request.Params["signed_request"]);

Documentation

You can find the documentation of Facebook C# SDK at http://docs.csharpsdk.org/. You can fork https://github.com/facebook-csharp-sdk/facebook-csharp-sdk.github.com/tree/master/docs repository and send us pull requests.

Although we think the current pre-release of v6 has been highly improved in the API point of view, we are still open to changes depending on the feedback we receive. We would love to hear your feedback before the beta release and the final RTW.

Install-Package Facebook -version 6.0.1-alpha

Make sure to also read the Facebook C# SDK Roadmap by Nathan Totten for more details at http://blog.ntotten.com/2012/02/07/facebook-c-sdk-road-map/.

(This feature requires Facebook C# SDK v5.5 at minimum)

Facebook C# SDK supports a wide variety of .NET framework ranging from .NET 3.5/4.0, Silverlight 4.0/5.0 and Windows Phone. Two months back we introduced support for Developer Preview version of .NET 4.5 with Facebook C# SDK v5.3 which allows you to take advantage of async/await and Task Parallel Library – TPL (You can read more on it here) and couple of weeks back we introduced support for TPL in Silverlight 5 with v5.4. With v5.5 we are introducing support for creating Windows Metro Style Apps. (Couple of weeks back I tweeted (@prabirshrestha) about porting SimpleJson (JSON library) and FluentHttp.Core (mockable HTTP web request wrapper for .NET) to WinRT which has made it a breeze to port Facebook C# SDK to WinRT.)

Since Windows 8 has not even hit BETA stage we will not be providing compiled binaries of Facebook.dll nor be distributing it via NuGet (package manager for .NET) anytime soon.

You will need a copy of Windows 8 Developer preview with Visual Studio 11 (express edition is supported) installed in order to compile Facebook.dll compatible with Windows 8 Metro apps. A new solution file called “Facebook-WinRT.sln” has been added in the Source folder. There is also a new sample “CS-WinRT.sln” which demonstrates authenticating the user and getting access token and then making Get/Post/Delete requests to Facebook server using async/await.

Here is a hello world example:

public async FacebookHelloWorld()
{
    try
    {
        var fb = new FacebookClient();
        dynamic result = await fb.GetTaskAsync("4");
        txtName.Text = result.name;
    }
    catch(FacebookApiException ex)
   {
       // catch facebook exceptions
   }
   catch(Exception ex)
   {
     // catch other non facebook exceptions: like no internet connection
   }
}

Happy New Year and have fun writing a Facebook Metro App and don’t forget to apply for Window 8 First Apps Content.