Posting to Facebook Page using C# SDK from offline app

If you want to post to a facebook page using the Facebook Graph API and the Facebook C# SDK, from an “offline” app, there’s a few steps you should be aware of.

First, you need to get an access token that your windows service or app can permanently use. You can get this by visiting the following url (all on one line), replacing [ApiKey] with your applications Facebook API key.

http://www.facebook.com/login.php?api_key=[ApiKey]&connect_display=popup&v=1.0
&next=http://www.facebook.com/connect/login_success.html&cancel_url=http://www.facebook.com/connect/login_failure.html
&fbconnect=true&return_session=true&req_perms=publish_stream,offline_access,manage_pages&return_session=1
&sdk=joey&session_version=3

In the parameters of the URL you get redirected to, this will give you an access key. Note however, that this only gives you an access key to post to your own profile page. Next, you need to get a separate access key to post to the specific page you want to access. To do this, go to

https://graph.facebook.com/[YourUserId]/accounts?access_token=[AccessTokenFromAbove]

You can find your user id in the URL when you click on your profile image. On this page, you will then see a list of page IDs and corresponding access tokens for each facebook page. Using the appropriate pair,you can then use code like this:

var app = new Facebook.FacebookApp(_accessToken);
var parameters = new Dictionary
{
    { "message",  promotionInfo.TagLine },
    { "name" ,  promotionInfo.Title },
    { "description" ,  promotionInfo.Description },
    { "picture", promotionInfo.ImageUrl.ToString() },
    { "caption" ,  promotionInfo.TargetUrl.Host },
    { "link" ,  promotionInfo.TargetUrl.ToString() },
    { "type" , "link" },
};
app.Post(_targetId + "/feed", parameters);

And you’re done!

Applying app.config transformations (in the same way as web.config)

Visual Studio 2010 doesn’t have the same support for app.config files in the way that their web projects do, in order to vary connection strings and other configuration settings for different release modes – a real shame. You can vote on the issue here. In the meantime though, the ASP.NET team have a fix, detailed here.

All you need to do is save their custom targets file, add an imports tag immediately before the closing tag:

  ...
  <Import Project="$(MSBuildExtensionsPath)\Custom\TransformFiles.targets" />
</Project>

And add a TransformOnBuild metadata property to each config file you want transformed. So

<None Include="app.config" />

becomes

<None Include="app.config">
  <TransformOnBuild>true</TransformOnBuild>
</None>

(note you don’t need to do this on the configuration specific config files such as app.release.config). Then you can write your app.Release.config and similar files in the same way you do for web.config files. Sweet!

web.config transformations for NHibernate

If you’re trying to use web.config transformations in VS 2010 with nHibernate you might be hitting the same issue I’ve been getting the transformation to match the hibernate-configuration node. The reason is because you have to specify an xmlns="urn:nhibernate-configuration-2.2" attribute as part of the configuration:

<configuration>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.connection_string">connection string</property>
      ...
    </session-factory>
  </hibernate-configuration>
</configuration>

To fix, just set the namespace on the target node in the transformation file like this:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
               xmlns:hib="urn:nhibernate-configuration-2.2">
  <hib:hibernate-configuration>
    <hib:session-factory>
      <hib:property xdt:Transform="Replace" xdt:Locator="Match(name)" name="connection.connection_string">your connection string</hib:property>
    </hib:session-factory>
  </hib:hibernate-configuration>
</configuration>

Running OpenX under IIS with PHP 5.3 – date_default_timezone_get errors

I run OpenX (an open source ad serving platform) under IIS and PHP …. but after upgrading to PHP 5.3 noticed the following error appearing in the PHP error logs file (c:\windows\temp\php-errors.log by default).


PHP Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/London' for '1.0/DST' instead in C:\inetpub\wwwroot\openx-2.8.5\www\delivery\spc.php on line 191

The solution to make this error go away is simply to specify a default timezone in the php.ini configuration file. In my case this looked like:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Europe/London"

PHP 5.3 and IIS 7 – beware of MySQL issues with IPv6

I’ll keep this short and sweet as it’s covered in depth elsewhere. After installing PHP 5.3 suddenly my website stopped working – but instead of throwing errors, it simply sat there and eventually timed out (with no error). Turns out there are issues with both PHP and MySQL around IPv6. The most common solution is “turn off IPv6 support” – not a reassuring answer.

On the PHP front, the issue seems to be around fsockopen which works fine in 5.3.0 but not in 5.3.2. The major issue for most people though is that the MySQL driver doesn’t properly support IPv6 if you’re using a hostname (such as localhost) to connect instead of an IP address, particularly when localhost resolves to “::1”.

I’m not sure what changed in PHP 5.3.2 to bring this to the surface, but the solution is either to switch to using an IP address, for which there are other good reasons to do so, or modify your hosts file (c:\windows\system32\drivers\etc) and change the line the starts with “::1 localhost” to “#::1 localhost”.

Hope this helps someone!

Beware: Upgrade to ASP.NET MVC 2.0 with care if you use AntiForgeryToken

If you’re thinking of upgrading to MVC 2.0, and you take advantage of the AntiForgeryToken support then be careful – you can easily kick out all active visitors after the upgrade until they restart their browser. Why’s this?
For the anti forgery validation to take place, ASP.NET MVC uses a session cookie called “__RequestVerificationToken_Lw__”.

This gets checked for and de-serialized on any page where there is an AntiForgeryToken() call. However, the format of this validation cookie has apparently changed between MVC 1.0 and MVC 2.0.
What this means is that when you make to switch on your production server to MVC 2.0, suddenly all your visitors session cookies are invalid, resulting in calls to AntiForgeryToken() throwing exceptions (even on a standard GET request) when de-serializing it:

[InvalidCastException: Unable to cast object of type 'System.Web.UI.Triplet' to type 'System.Object[]'.]
System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken) +104

[HttpAntiForgeryException (0x80004005): A required anti-forgery token was not supplied or was invalid.]
System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken) +368
System.Web.Mvc.HtmlHelper.GetAntiForgeryTokenAndSetCookie(String salt, String domain, String path) +209
System.Web.Mvc.HtmlHelper.AntiForgeryToken(String salt, String domain, String path) +16
System.Web.Mvc.HtmlHelper.AntiForgeryToken() +10
<snip>

So you’ve just kicked all your active users out of your site with exceptions until they think to restart their browser (to clear the session cookies).

The only work around for now is to either write some code that wipes this cookie – or disable use of AntiForgeryToken() in your MVC 2.0 site until you’re confident all session cookies will have expired. That in itself isn’t very straightforward, given how frequently people tend to hibernate/standby their machines – the session cookie will only clear once the browser has been shut down and re-opened.

Hope this helps someone out there!

Including Spark views in VS 2010 web deployments

Visual Studio 2010 includes much improved deployment tools – but by default it only includes files “needed to run this application”. If you’re using the Spark view engine for ASP.NET MVC, then the Spark views aren’t considered one of them!

The trick is to ensure your .spark views have a build action of “Content” instead of the default “None”. Clearly remembering this each time would get somewhat tedious, so instead you can add the following registry entries:



Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftVisualStudio10.0Projects{F184B08F-C81C-45f6-A57F-5ABD9991F28F}FileExtensions.spark]
"DefaultBuildAction"="Content"

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftVisualStudio10.0Projects{FAE04EC0-301F-11d3-BF4B-00C04F79EFBC}FileExtensions.spark]
"DefaultBuildAction"="Content"

(just add this to a .reg file and run it)

developerFusion community relaunches

As some of you will know, I’ve run the developerFusion community for many years now, as a part-time hobby. Now, some big changes are afoot! 2 months ago I packed in my day job to focus on the site full-time, and have now made the first big step and re-launched the site.

You can check it out at http://www.developerfusion.com/.

This is just the first step along the road, but an exciting one (for me at least!). The new site is going to make it even easier for developers around the world to connect with each other, and discover what’s going on in their local area – be that events, user groups, blogs or just general discussion. We’ll also be bringing a wider range of technical articles and focused developer news.

If you have any feedback, feel free to get in touch – the site is here for you! If you twitter, stay tuned at http://twitter.com/developerfusion for more updates.