Building a Facebook Graph API application using ASP.NET

Background

Recently I needed to build a Facebook Share style application that gave me more control over the content that was posted on a users Facebook wall. Implementing this as a Facebook Application also allowed me to do some custom processing when the user completed the share process.

To do this I used Facebook’s Graph API. The Graph API is the core of Facebook’s system. It enables the developer to read and write Facebook data (provided the appropriate permisions exist). There’s a lot more information about the Graph API on the Facebook Developers Site

When the user clicks ‘Share’ they’re presented with the same Facebook style dialog that they’re used to, but where my application controls all of the data that they see

Finally, when the user completes the share process, the information shows up on their wall as it normally would, but I also get a callback letting me know that they completed the process which allows me to do any custom processing.

You’ll need to create a Facebook Application. You can do this at the Facebook Developers site. I’ve called the one that I use for this sample ‘My ASP.NET Application’. Once you have the application setup you’ll need to make note of the ‘App ID’ from Facebook as we’ll need this information later.


Using the Code

I like to create a ‘Controls’ folder in my ASP.NET Projects to contain any UserControls that I create/use in that project. To create my FacebookShare.ascx I right-clicked on my ‘Controls’ folder then selected ‘Add->New Item’ and finally chose ‘Web User Control’.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FacebookShare.ascx.cs" Inherits="FacebookApplication.Controls.FacebookShare" %>

    
facebook likeus Share with Facebook
</div>

The codebehind for the UserControl is defines the model for the data our control cares about.

namespace FacebookApplication.Controls
{
    public partial class FacebookShare : System.Web.UI.UserControl
    {
        public string Message { get; set; }
        public string Prompt { get; set; }
        public string Name { get; set; }
        public string Caption { get; set; }
        public string Description { get; set; }
        public string Href { get; set; }
        public string Image { get; set; }
        public string ApplicationId { get; set; }
    }
}

The code to use the Facebook Share control looks like this:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="FacebookApplication._Default" %>

<%@ Register src="Controls/FacebookShare.ascx" tagname="FacebookShare" tagprefix="uc1" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    /Scripts/jquery-1.4.1.min.js
</asp:Content>

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        A customizable Facebook Share button
    </h2>
    <p>
        <uc1:FacebookShare ID="FacebookShare1" runat="server" ApplicationId="12345" Message="Message"
            Name="Name" Caption="Caption" Description="Description" Href="http://mourfield.com"
            Image="http://www.gravatar.com/avatar/41e139e92663400389c2c9d95a865820.png" /></p>
    <p>
        You can also find <a href="http://developers.facebook.com/docs/"
            title="Facebook Developer Docs">documentation on Facebook at Facebook Developers</a>.
    </p>
</asp:Content>

Hopefully, you’ll be able to use this as a starting place for your applications. There is much more that can be done using Facebook’s Graph API. This example barely scratches the surface of what is possible.

You can also find more information including documentation on Facebook at Facebook Developers.

Using jQuery Mobile with ASP.NET MVC

Background

jQuery Mobile is a web UI framework from the same guys over at the jQuery Project. jQuery Mobile is built on top of the jQuery Core and jQuery UI projects with the intent of bringing a consistent UI framework to mobile platforms.

To get started using the jQuery Mobile framework you can either download the .js and .css files from http://jquerymobile.com/download/ or you can use the cdn-hosted versions as well.

The structure of a page that uses jQuery Mobile is pretty straightforward. First the page must start with an HTML5 ‘doctype’. Also, in the ‘head’, references to jQuery, jQuery Mobile and the mobile theme CSS are all required.

Next, the mobile page is defined inside the ‘body’ tag. Each ‘page’ is defined within a ‘div’ element with the data-role=”page” attribute. Inside the ‘page’ element, there are a set of child ‘divs’ with data-roles of “header”, “content”, and “footer”. Note, these are optional, but are typically used to provide a consistent look-and-feel. A very simple jQuery Mobile page would look like this:


 

    
        
        
        
    
    

Page Title

 

Page content goes here.

 

Page Footer

 


Incorporating with ASP.NET MVC

I like the idea of incorporating jQuery Mobile as an alternate mobile view in ASP.NET MVC because it allows us to use the same controllers and models as we would with our regular or desktop views while giving us the flexibility of delivering content that is mobile friendly.

To incorporate jQuery Mobile templates into an ASP.NET MVC site I like the approach that Scott Hanselman take with ‘A Better ASP.NET MVC Mobile Device Capabilities ViewEngine‘. Basically what Scott is doing is building a custom view engine for ASP.NET MVC that redirects the view to some relative route based on if the incoming request is coming from a mobile browser (or not).

So, to putting the whole thing together goes something like this: I’m starting with a new ASP.NET MVC 3 Project, but you should be able to follow these steps to start using jQuery Mobile in your existing ASP.NET MVC applications as well. The first step is to include the custom view engine and mobile helpers from Scott Hanselman’s article. I just created two new classes in a Helpers folder in my project. Looks like this:

Step1

Next, again from Scott’s article, you’ll need to ‘plug-in’ the CustomMobileViewEngine into MVC. To do this I added this code to my Application_Start().


 

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.AddGenericMobile();
    ViewEngines.Engines.Add(new RazorViewEngine());
    ...
}

The next step is to add either a mobile MasterPage or Layout page, depending on which view engine you’re using. In my case, I’m using the Razor view engine in ASP.NET MVC 3, but the basic techniques are the same with the WebForms view engine as well. To do this right-click on the Views\Shared directory in your project and select ‘Add->New Item’. Select the appropriate template type for your projects view engine; A View Master Page for ASPX or a Layout Page for Razor. And name the page appropriately. I’m calling mine ‘_LayoutMobile.cshtml’. My jQuery Mobile ready layout page looks like this:


 

    
    
    


My MVC Application

 

 

@RenderBody()

 

Page Footer

 

 


When it’s all said and done, my project’s view directory structure looks like this:

To create the Views for the Home controller I right-clicked on the Views\Home directory and added a new folder named ‘Mobile’. Next, I right-clicked on the newly created Mobile folder and selected ‘Add->View’. In the Add View dialog, I filled out the View name and made sure to select the appropriate layout or master page for the mobile templates that I created earlier.

Step2

The code for my Index view page looks like


 

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_LayoutMobile.cshtml";
}
    • @Html.ActionLink(“Home”, “Index”, “Home”)

 

  • @Html.ActionLink(“About”, “About”, “Home”)

 

 

 

@ViewBag.Message

To learn more about ASP.NET MVC visit http://asp.net/mvc.

and my About view page looks like


 

@{
    ViewBag.Title = "About";
    Layout = "~/Views/Shared/_LayoutMobile.cshtml";
}

About

Put content here.

Here’s what the views look like rendered on a mobile device:

 

Finally

Now what I’ve presented here is a very basic example, but hopefully, you can see the power of using a technique like this one to share the controllers and models, but change out the views based on the type of browser that is making the request.

I’d encourage you to head over and check out the documentation and demos for jQuery Mobile at http://jquerymobile.com/. This will help you get a better feel for how to accomplish your specific mobile UI tasks.

Custom Configuration Sections in .NET

Most .NET developers will need to store some application configuration information at some point. Most times developers choose to use the appSettings section in the configuration file for this purpose. Here’s an example of an appSettings configuration section:

    
    
    
     ...

Over time the number of configuration items tends to grow and managing them can become confusing. What you end up with is a seemingly endless list of key value pairs that are difficult to manage. Additionally the code required the access there values can start to get tedious.

using System;
using System.Configuration;

namespace Before
{
    class Program
    {
        static void Main(string[] args)
        {
            // Load Misc Settings
            decimal standardHandlingFee = Convert.ToDecimal(ConfigurationManager.AppSettings["StandardHandlingFee"]);
            int pageSize = Convert.ToInt32(ConfigurationManager.AppSettings["PageSize"]);

            // ... do work ...
        }
    }
}

.NET has the given developers the ability simplify this process by creating custom configuration sections. These custom configuration sections can help turn unstructured, untyped data into strongly-typed, straightforward elements. Basically, taking the almost meaningless key-value pairs and turning them into something more meaningful.

 

There are 3 pieces that makeup the custom configuration; a class that inherits from System.Configuration.ConfigurationSection; “registering” your configuration class in the configSections of your configuration file; and the XML configuration itself.

First is the class that handles how we access the configuration data.

using System;
using System.Configuration;

namespace After.Configuration
{
    public class TestAppConfigProviderSection : ConfigurationSection
    {
        public static readonly TestAppConfigProviderSection Current = (TestAppConfigProviderSection)ConfigurationManager.GetSection("testAppConfigProvider");

        [ConfigurationProperty("StandardHandlingFee", DefaultValue = "4.95")]
        public decimal StandardHandlingFee
        {
            get { return (decimal)base["StandardHandlingFee"]; }
            set { base["StandardHandlingFee"] = value; }
        }

        [ConfigurationProperty("PageSize", DefaultValue = "10")]
        public int PageSize
        {
            get { return (int)base["PageSize"]; }
            set { base["PageSize"] = value; }
        }
    }
}

This class is pretty straightforward, but there are some key things to take note of. First, the main ConfigurationSection class must derive from the System.Configuration.ConfigurationSection class.

 

Also, within the TestAppConfigProviderSection class I use a singleton style approach with the Current member. This helps make accessing the properties within the configuration section easy.

The configuration properties that the class is exposing should use the ConfigurationProperty attribute. The name that gets passed in this attribute should match the attribute name in the configuration file.

“Registering” our configuration section is done by adding a section the the configSections of the application’s .config file. The XML configuration is restructured to match how it is defined in our class. Here’s the new .config file after being refactored.


  
    

Here’s our example code again, but using the custom configuration sections.

using System;
using After.Configuration;

namespace After
{
    class Program
    {
        static void Main(string[] args)
        {
            // Load Misc Settings
            decimal standardHandlingFee = TestAppConfigProviderSection.Current.StandardHandlingFee;
            int pageSize = TestAppConfigProviderSection.Current.PageSize;

            // ... do work ...
        }
    }
}

It is also possible to load the custom configuration sections from an external file like so:


  
    

Where testApp.config looks like this:


One important note on using this method, you must make sure that you change the Copy to Output Directory property on the new .config file to either ‘Copy if newer’ or ‘Copy always’. Otherwise the file won’t get copied to the projects bin directory and the ConfigurationManager won’t be able to load the file.

The benefits of using a custom configuration section handler are significant. Using the handler code is pretty straightforward and gives you less clutter in the appSettings as well as strong typing of your configuration elements.

 

How to send a email message using Telnet

Occasionally I’ve had to troubleshoot sending email messages to a particular SMTP server by simulating a mail client (or .NET mail code) by using the telnet client. Here’s how I do it on Windows:

  1. open the command prompt
  2. type: telnet smtpserver.domain.com 25 <press enter>
  3. type: helo server.com <press enter>
  4. type: mail from: you@domain.com  <press enter>
  5. type: rcpt to: someone@domain.com <press enter>
  6. type: data <press enter>
  7. write a test message. Typically I type something like: hello world! <press enter>
  8. to send the message type a single period (.) on a line by itself and of course <press enter>

Using Web Slices with Nerd Dinner

The web slices feature was introduced in IE8 and allows users to subscribe to content directly within a webpage. Web slices allow web site developers to deliver content to the user’s browser no matter what the user is doing. When the content inside the web slice is modified, the user is notified through their Favorites bar and they can respond however they deem appropriate.

To define it, the element that encloses the region of the web slice needs to have the class ‘hslice’ and an unique id. Inside the web slice, items with the class ’entry-title’ will represent the title in the web slice window. Also, items with the class ‘entry-content’ represent the actual content of the web slice.

For those that are interested, the checkin of this code is on the NerdDinner CodePlex site. Here is the markup we created for NerdDinner.com to make the Popular Dinners section of the site available as a web slice.

<div id="2" class="hslice">
<h2 class="entry-title">Popular Dinners</h2>
<div></div>
<a rel='feedurl' href='/Dinners/WebSlicePopular' style='display:none;'></a> </div>

which looks like this when it’s rendered on the page: and looks like this in the Favorites bar: The code added to the controller class to handle this behavior looks like this:

public ActionResult WebSlicePopular()
{
    ViewData[""Title""] = ""Popular Nerd Dinners"";
    var model = from dinner in dinnerRepository.FindUpcomingDinners()
                                orderby dinner.RSVPs.Count descending
                                select dinner;
    return View(""WebSlice"",model.Take(5));
}

And the View is:

&lt;%@ Page Language=&quot;&quot;C#&quot;&quot; Inherits=&quot;&quot;System.Web.Mvc.ViewPage"" ContentType=""text/html"" %&gt;





    &lt;


    <div>
        <div>
            <h2></h2>
            <div>
                <ul>
                    
                    <li>
                        
                        on <strong>
                            
                            </strong> at
                        
                    </li>
                    
                </ul>
            </div>
        </div>
        <a></a>
    </div>


The MSDN site has some great Web Slice resources, including tutorials to help you get started.

Seo Improvements with ASP.NET 4

ASP.NET 4 had been released for a few months now so I thought that I’d take a look at two new properties added to the System.Web.Page class – MetaDescription and MetaKeywords. These two attributes represent corresponding meta tags in your page and get rendered on the page like so:


    your DESCRIPTIVE KEYWORDS title goes here
    
    

Both the description and keywords meta tags can be important in search engine optimization or (SEO). Specifically, Google (and others) use the description meta tag for improving search listings. (For more details, see Improve snippets with a meta description makeover on the Google Webmaster Central blog.) Also, according to Meta Keywords Advice on the Search Engine Guide Web site, Google no longer uses the contents of the keywords meta tag in their search indexes. It’s my understanding that Windows Live Search doesn’t use the keywords meta tag in determining it’s page rankings, but others may, so it doesn’t hurt to build dynamic content in the keywords meta tag.

These new properties may seem a bit trivial, but prior to ASP.NET 4 if you wanted to provide dynamic values for either of these properties you would have to inject the values into the header. There are two ways of doing this. The first is by adding Literal controls into the element and setting their text in the CodeBehind (Method 1). The other was by creating a HtmlMeta control in the code behind and add them to the control collection for the header element (Method 2).

Here’s an example of Method 1:

MetaOld.aspx







    
    
    


    
    

MetaOld.aspx.vb


Partial Class MetaOld
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Page.Title = ""your DESCRIPTIVE KEYWORDS title goes here""
        metaDescription.Text = """"
        metaKeywords.Text = """"
    End Sub
End Class

Alternatively, here’s an example of Method 2. Notice that there is no markup required in the aspx page to support this technique:

MetaOld2.aspx







    


    
    

MetaOld2.aspx.vb


Partial Class MetaOld2
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Page.Title = ""your DESCRIPTIVE KEYWORDS title goes here""

        Dim metaDescription As New HtmlMeta
        Dim metaKeywords As New HtmlMeta

        metaDescription.Name = ""DESCRIPTION""
        metaDescription.Content = ""Your keyword rich marketing sales-pitch meta description goes here""

        metaKeywords.Name = ""KEYWORDS""
        metaKeywords.Content = ""your keywords,go here,separated by a comma,but not a space""

        Page.Header.Controls.Add(metaDescription)
        Page.Header.Controls.Add(metaKeywords)
    End Sub
End Class

Since ASP.NET 4, Microsoft introduced the MetaDescription and MetaKeywords attributes in the System.Web.UI.Page class achieving the same behavior is much simpler. You can set these attributes at run time which allows you to generate the content dynamically and provide better descriptions for a particular page (Method 3). Alternatively, you can set the MetaDescription and MetaKeywords attributes declaratively in the @ Page directive at the top of your aspx page (Method 4).

Here’s Method 3, in this example using only the new attributes in the codebehind there isn’t anything needed in the aspx markup to support this.

MetaNew.aspx







    


    
    

MetaNew.aspx.vb


Partial Class MetaNew
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Page.Title = ""your DESCRIPTIVE KEYWORDS title goes here""
        Page.MetaDescription = ""Your keyword rich marketing sales-pitch meta description goes here""
        Page.MetaKeywords = ""your keywords,go here,separated by a comma,but not a space""
    End Sub
End Class

Method 4, since these attributes are a part of the Page class you can use them declaratively in the Markup as well:

MetaNew2.aspx







    your DESCRIPTIVE KEYWORDS title goes here


    
    

An important note: these properties share a couple of behaviors with the Title attribute of the Page class. First, if there are no description or keywords meta tags in the head element, setting either the MetaDescription or MetaKeywords attributes will cause the meta tags are added to the page when it is rendered. Second, if there are already description or keywords meta tags in the head element, the MetaDescription and MetaKeywords attributes will act as get and set methods for the contents of the existing tags.

What’s causing this ‘Hashtable insert failed. Load factor too high.’ error?

On a number of occasions I’ve seen this error on an ASP.NET Web Application that’s under a fairly heavy load.

Hashtable insert failed. Load factor too high.  At:
    at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
    at System.Runtime.Serialization.SerializationEventsCache.GetSerializationEventsForType(Type t)
    at System.Runtime.Serialization.SerializationObjectManager.RegisterObject(Object obj)
    
    at System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer)

The problem is that it just doesn’t happen once or twice and go away. It requires a restart of the W3SVC service which takes the entire web server down. After looking at the stack trace in the error my first thought was that there was a Hashtable being used in the application that wasn’t thread safe. Unfortunately, it wasn’t that easy. There were no Hashtables being used directly in the code. So I decided to use a Support Services call to try to get to the bottom of what was going on.

After a number of back-and-forths, Microsoft sent a patch (which is now available publically at http://support.microsoft.com/kb/968432 ). They didn’t explain what the problem was, so I fired up ildasm and looked at the changes. What I noticed were changes to a number of methods in the System.ComponentModel.ReflectTypeDescriptionProvider class. This class is a .NET internal class that is responsible for providing Type information about particular classes.

If you look at the Before and After snippets below, you’ll see the kind of changes that were made to all of the methods in this class. Basically, the code that is responsible for building a Hashtable wasn’t thread safe, hence the additional lock in the After snippet.

Before (System.dll version 2.0.50727.4016):

private static Attribute[] ReflectGetAttributes(Type type)
{
    if (_attributeCache == null)
    {
        lock (_internalSyncObject)
        {
            if (_attributeCache == null)
            {
                _attributeCache = new Hashtable();
            }
        }
    }

    Attribute[] array = (Attribute[]) _attributeCache[type];
    if (array == null)
    {
         object[] customAttributes = type.GetCustomAttributes(typeof(Attribute), false);
         array = new Attribute[customAttributes.Length];
         customAttributes.CopyTo(array, 0);
         _attributeCache[type] = array;
    }
    return array;
}

After (System.dll version 2.0.50727.4038):

private static Attribute[] ReflectGetAttributes(Type type)
{
    if (_attributeCache == null)
    {
        lock (_internalSyncObject)
        {
            if (_attributeCache == null)
            {
                _attributeCache = new Hashtable();
            }
        }
    } 

    Attribute[] array = (Attribute[]) _attributeCache[type];
    if (array == null)
    {
        lock (_internalSyncObject)
        {
            array = (Attribute[]) _attributeCache[type];
            if (array == null)
            {
                object[] customAttributes = type.GetCustomAttributes(typeof(Attribute), false);
                array = new Attribute[customAttributes.Length];
                customAttributes.CopyTo(array, 0);
                _attributeCache[type] = array;
            }
        }
    }
    return array;
}