ENTERPRISE

Visual Studio 2010 : Writing Custom Facebook Applications - Querying Data from Facebook

3/5/2012 11:24:35 AM
The CanvasIFrameMasterPage class in Facebook.Web.dll contains all the properties and methods that you need to access Facebook data. The main class that you use in the Facebook SDK is Facebook.Rest.Api. This class is the window into the world of Facebook development. If you created the Weather2.aspx file to use the master page , accessing this class from code is as easy as the following line:
this.Master.Api

This class provides many methods and properties for accessing Facebook data, but perhaps the easiest and most efficient is through the use of the Facebook Query Language (FQL). You can find out more about FQL from http://wiki.developers.facebook.com/index.php/FQL. FQL uses a Structured Query Language (SQL) syntax to access data from the Facebook databases and is more efficient because the SDK allows you to batch queries into a MultiQuery object for execution. Executing multiple queries at once saves round-trip accesses to Facebook servers from across the network. In the PageLoad event of Weather2.aspx, you can get the profile information of the logged-in user as well as information about friends of the logged in user as follows:

protected void Page_Load(object sender, EventArgs e)
        {
            System.Console.WriteLine(this.Master.Api.Session.UserId);

            this.Master.Api.Connect.Session.Login();

            long userId = this.Master.Api.Users.GetLoggedInUser();

            Dictionary<string, string> multiQuery = new Dictionary<string,
     string<();

            multiQuery.Add("query1", "SELECT name, current_location,pic_square
     from user WHERE uid=" + userId);
            multiQuery.Add("query2", "SELECT name, current_location, pic_square,
     uid from user WHERE uid IN (SELECT uid2 from friend WHERE uid1="+ userId +
     ")");

             foreach (Facebook.Schema.fql_result fqlResult in this.Master.Api.Fql.
     Multiquery(multiQuery))
             {
                if (fqlResult.name == "query1")
                {
                    this.OnUserQueryComplete(fqlResult.fql_result_set.
    ToString());
                }
                else if (fqlResult.name == "query2")
                {
                    this.OnFriendQueryComplete(fqlResult.fql_result_set.
    ToString());
                }
           }
        }

					  

The preceding code deserves some explanation. When Facebook loads your Weather2.aspx page, it uses the session key information for the user that is currently logged into Facebook on the computer in which the page is executing. Calling GetLoggedInUser returns the User Id for that user, which is a numeric value. After you have the User Id, you can query the Facebook database for information about that user. In this case, two queries are required. The first query queries information from the logged-in user's profile. In particular, the query retrieves the name, current_location, pic_square columns from the user table. The following FQL query retrieves user information:

"SELECT name, current_location,pic_square from user WHERE uid=" + userId;

1. Finding out about your friends

The second query retrieves the name, current_location, pic_square, and uid columns from the user table for each user that is a friend of the logged in user. You query the list of friends from the uid2 column of the friend table in the Facebook database. The FQL query is a little more complex:

"SELECT name, current_location, pic_square, uid from user WHERE uid IN (SELECT
    uid2 from friend WHERE uid1="+ userId + ")"

					  

The Multiquery method of the Facebook.Rest.Fql class batches both queries and sends them to the Facebook server. The Facebook server returns a result set for each of the queries. The FQL APIs return query results in XML format for storage in a DataSet object or for manual parsing. After the query results are retrieved, you can populate the user and friend data on the WeatherControl Web User Control as follows:

public class ProfileInfo
    {
        private string _City;
        private string _State;
        private string _PostalCode;
        private string _ProfileImage;
        private string _Name;


        public string City
        {
            get
            {
                return (_City);
            }
            set
            {
                _City = value;
            }
        }

        public string State
        {
            get
            {
                return (_State);
            }
            set
            {
                _State = value;
            }
        }

        public string PostalCode
        {
            get
            {
                return (_PostalCode);
            }
            set
            {
                _PostalCode = value;
            }
        }

					  

public string ProfileImage
        {
            get
            {
                return (_ProfileImage);
            }
            set
            {
                _ProfileImage = value;
            }
        }

        public string Name
        {
            get
            {
                return (_Name);
            }
            set
            {
                _Name = value;
            }
        }
    }

private void OnFriendQueryComplete(string result)
        {
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(result);

            XmlNodeList userNodes = xmlDoc.GetElementsByTagName("user");

            List<ProfileInfo> friends = new List<ProfileInfo>();

            foreach (XmlNode node in userNodes)
            {
                ProfileInfo friend = new ProfileInfo();

                foreach (XmlNode userNode in node.ChildNodes)
                {

                    if (userNode.Name == "pic_square")
                    {
                        friend.ProfileImage = userNode.InnerText;
                    }
                    else if (userNode.Name == "name")
                    {
                        friend.Name = userNode.InnerText;
                    }
                    else if (userNode.Name == "current_location")
                    {
                        foreach (XmlNode locationNode in userNode.ChildNodes)
                        {
                            if (locationNode.Name == "city")
                            {
                                friend.City = locationNode.InnerText;
                            }

					  

else if (locationNode.Name == "state")
                            {
                                friend.State = locationNode.InnerText;
                            }
                            else if (locationNode.Name == "zip")
                            {
                                friend.PostalCode = locationNode.
                            }
                        }
                    }
                }
                friends.Add(friend);
            }

            this.MyWeather.Friends = friends;
        }

        private void OnUserQueryComplete(string result)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string strUser = string.Empty;
            string strImageUrl = string.Empty;
            xmlDoc.LoadXml(result);

            XmlNodeList imageNodes = xmlDoc.GetElementsByTagName("pic

            if (imageNodes != null && imageNodes.Count > 0)
            {
                strImageUrl = imageNodes[0].InnerText;
            }

            XmlNodeList userNodes = xmlDoc.GetElementsByTagName("name");

            if (userNodes != null && userNodes.Count > 0)
            {
                strUser = userNodes[0].InnerText;
            }

            XmlNodeList nodes = xmlDoc.GetElementsByTagName("current

            string strCity = string.Empty;
            string strState = string.Empty;
            string strZip = string.Empty;

            foreach (XmlNode node in nodes)
            {
                foreach (XmlNode locationNode in node.ChildNodes)
                {
                    if (locationNode.Name == "city")
                    {
                        strCity = locationNode.InnerText;
                    }
                    else if (locationNode.Name == "zip")
                    {
                        strZip = locationNode.InnerText;
                    }
                    else if (locationNode.Name == "state")
                    {
                        strState = locationNode.InnerText;
                    }
                }
            }

					  

if (!string.IsNullOrEmpty(strZip))
            {
                string strLocation = string.Empty;

                if (!string.IsNullOrEmpty(strCity))
                {
                    strLocation = strCity;
                }
                if (!string.IsNullOrEmpty(strState))
                {
                    strLocation += ("," + strState);
                }

                this.MyWeather.CurrentLocation = strLocation;
                this.MyWeather.ProfileUser = strUser;
                this.MyWeather.ProfileUserImage = strImageUrl;
            }
    }

2. Accessing weather data for your friend's location

After you have the profile information containing user and location information for the logged-in user as well as that user's friends, you can get weather information for their location in the WeatherControl.ascx.cs code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Text;
using System.IO;
using System.Xml;

namespace CurrentLocalWeather
{
    public partial class WeatherControl : System.Web.UI.UserControl
    {
        private string _Url = "http://www.google.com/ig/api?weather=";
        private string _BaseUrl = "http://www.google.com";

        private CurrentConditions _CurrentConditions = new CurrentConditions();
        private List<ForecastConditions> _ForecastConditions = new
    List<ForecastConditions>();
        private ForecastInformation _ForecastInformation = new
    ForecastInformation();
        private string _CurrentLocation;
        private string _ProfileUser;
        private string _ProfileUserImage;

        private List<ProfileInfo> _Friends;

        public List<ProfileInfo> Friends
        {
            get
            {
                return (_Friends);
            }

					  

set
            {
                _Friends = value;
            }
        }

        public string CurrentLocation
        {
            get
            {
                return (_CurrentLocation);
            }
            set
            {
                this._CurrentLocation = value;
            }
        }

        public string ProfileUser
        {
            get
            {
                return (_ProfileUser);
            }
            set
            {
                _ProfileUser = value;
            }
        }

        public string ProfileUserImage
        {
            get
            {
                return (_ProfileUserImage);
            }
            set
            {
                _ProfileUserImage = value;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                this.DropDownFriendList.DataSource = this._Friends;
                this.DropDownFriendList.DataTextField = "Name";

                this.DropDownFriendList.DataBind();

                string actualUrl = _Url + _CurrentLocation;

                this.LoadForecastData(actualUrl);

            }
            else
            {
                string actualUrl = _Url + _CurrentLocation;

                this.LoadForecastData(actualUrl);

					  

}
        }

        private void OnResponseReady(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;

            HttpWebResponse response = (HttpWebResponse)request.
     EndGetResponse(result);

            Encoding utf8Encoding = Encoding.UTF8;

            StreamReader responseStream = new StreamReader(response.
     GetResponseStream(), utf8Encoding);
            string content = responseStream.ReadToEnd();

            this._ForecastConditions.Clear();

            BuildForecastFromXml(content);

            UpdateDisplay();
        }

        private void BuildForecastFromXml(string xmlContent)
        {
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xmlContent);

            XmlNodeList forecastNodes = xmlDoc.GetElementsByTagName("forecast_
    information");

            foreach (XmlNode node in forecastNodes)
            {
                foreach (XmlNode forecastNode in node.ChildNodes)
                {
                    XmlAttributeCollection attrs = forecastNode.Attributes;

                    if (forecastNode.Name == "city")
                    {
                        this._ForecastInformation.City = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (forecastNode.Name == "postal_code")
                    {
                        this._ForecastInformation.PostalCode = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (forecastNode.Name == "forecast_date")
                    {
                        this._ForecastInformation.ForecastDate = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (forecastNode.Name == "current_date_time")
                    {
                        this._ForecastInformation.CurrentDateTime = attrs.
    GetNamedItem("data").InnerText;
                    }
                }

            }

					  

XmlNodeList currentConditionsNodes = xmlDoc.
    GetElementsByTagName("current_conditions");

            foreach (XmlNode node in currentConditionsNodes)
            {
                foreach (XmlNode currentNode in node.ChildNodes)
                {
                    XmlAttributeCollection attrs = currentNode.Attributes;

                    if (currentNode.Name == "condition")
                    {
                        this._CurrentConditions.ConditionData = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (currentNode.Name == "temp_f")
                    {
                        this._CurrentConditions.TempF = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (currentNode.Name == "temp_c")
                    {
                        this._CurrentConditions.TempC = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (currentNode.Name == "humidity")
                    {
                        this._CurrentConditions.HumidityData = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (currentNode.Name == "wind_condition")
                    {
                        this._CurrentConditions.WindData = attrs.
    GetNamedItem("data").InnerText;
                    }
                    else if (currentNode.Name == "icon")
                    {
                        this._CurrentConditions.IconData = attrs.
    GetNamedItem("data").InnerText;
                    }

                }
            }

            XmlNodeList forecastDataNodes = xmlDoc.
    GetElementsByTagName("forecast_conditions");

            foreach (XmlNode node in forecastDataNodes)
            {
                ForecastConditions cond = new ForecastConditions();

                foreach (XmlNode forecastDataNode in node.ChildNodes)
                {
                    XmlAttributeCollection attrs = forecastDataNode.Attributes;

                    if (forecastDataNode.Name == "day_of_week")
                    {
                        cond.DayOfWeek = attrs.GetNamedItem("data").InnerText;
                    }
                    else if (forecastDataNode.Name == "low")
                    {
                        cond.LowTemp = attrs.GetNamedItem("data").InnerText;
                    }

					  

else if (forecastDataNode.Name == "high")
                    {
                        cond.HighTemp = attrs.GetNamedItem("data").InnerText;
                    }
                    else if (forecastDataNode.Name == "icon")
                    {
                        cond.IconData = attrs.GetNamedItem("data").InnerText;
                    }
                    else if (forecastDataNode.Name == "condition")
                    {
                        cond.ConditionData = attrs.GetNamedItem("data").
    InnerText;
                    }
                }

                this._ForecastConditions.Add(cond);
            }

        }

        private void UpdateDisplay()
        {
            try
            {
                this.ForecastLabel1.Text = this._ForecastConditions[0].DayOfWeek;
                this.ForecastImage1.ImageUrl = this._BaseUrl + this._
    ForecastConditions[0].IconData;

                this.ForecastLabel2.Text = this._ForecastConditions[1].DayOfWeek;
                this.ForecastImage2.ImageUrl = this._BaseUrl + this._
    ForecastConditions[1].IconData;

                this.ForecastLabel3.Text = this._ForecastConditions[2].DayOfWeek;
                this.ForecastImage3.ImageUrl = this._BaseUrl + this._
    ForecastConditions[2].IconData;

                this.ForecastLabel4.Text = this._ForecastConditions[3].DayOfWeek;
                this.ForecastImage4.ImageUrl = this._BaseUrl + this._
    ForecastConditions[3].IconData;

                this.ForecastTemp1.Text = this._ForecastConditions[0].HighTemp +
    "/" + this._ForecastConditions[0].LowTemp;
                this.ForecastTemp2.Text = this._ForecastConditions[1].HighTemp +
    "/" + this._ForecastConditions[1].LowTemp;
                this.ForecastTemp3.Text = this._ForecastConditions[2].HighTemp +
    "/" + this._ForecastConditions[2].LowTemp;
                this.ForecastTemp4.Text = this._ForecastConditions[3].HighTemp +
    "/" + this._ForecastConditions[3].LowTemp;

                this.CurrentTempLabel.Text = this._CurrentConditions.TempF + " F
    / " + this._CurrentConditions.TempC +" C";
                this.CurrentConditionsImage.ImageUrl = _BaseUrl + this._
    CurrentConditions.IconData;
                this.City.Text = this._ForecastInformation.City;

                this.CurrentProfileImage.ImageUrl = this._ProfileUserImage;
                this.CurrentProfileName.Text = this._ProfileUser;

					  

}
             catch (System.Exception ex)
             {
                 System.Diagnostics.Debug.WriteLine(ex.Message);
             }
         }

         private void LoadForecastData(string url)
         {
             try
             {
                 HttpWebRequest request =
                     (HttpWebRequest)WebRequest.Create(url);

                 HttpWebResponse response = (HttpWebResponse)request.
     GetResponse();

                 Encoding utf8Encoding = Encoding.UTF8;

                 StreamReader responseStream = new StreamReader(response.
     GetResponseStream(), utf8Encoding);
                 string content = responseStream.ReadToEnd();

                 this._ForecastConditions.Clear();

                 BuildForecastFromXml(content);

                 UpdateDisplay();

            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        protected void DropDownFriendList_SelectedIndexChanged(object sender,
    EventArgs e)
        {
            if (this.IsPostBack)
            {
                ListItem item = this.DropDownFriendList.Items[this.
    DropDownFriendList.SelectedIndex];

                if (item != null)
                {
                    string userId = item.Value;

                    /*Now, find this user*/
                    IEnumerable<ProfileInfo> profile =
                        from friend in _Friends where friend.Name == userId
    select friend;

                    foreach (ProfileInfo info in profile)
                    {
                        _ProfileUser = info.Name;
                        _ProfileUserImage = info.ProfileImage;

					  

if (!String.IsNullOrEmpty(info.PostalCode))
                        {
                            _CurrentLocation = info.PostalCode;
                        }
                        else
                        {
                            string strLocation = string.Empty;

                            if (!String.IsNullOrEmpty(info.City))
                            {
                                strLocation += info.City;
                            }
                            if (!String.IsNullOrEmpty(info.State))
                            {
                                strLocation += ("," + info.State);
                            }
                            _CurrentLocation = strLocation;
                        }
                    }
                }
                string actualUrl = _Url + _CurrentLocation;

                this.LoadForecastData(actualUrl);

            }
        }
    }
}

					  

Finally, you add a reference to the WeatherControl.ascx WebUserControl to your Weather2.aspx page for rendering weather data as follows:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.
    Master" AutoEventWireup="true" CodeBehind="Weather2.aspx.cs"
    Inherits="CurrentLocalWeather.WebForm1" %>
<%@ Register TagPrefix="AndrewMoore" TagName="Weather" Src="WeatherControl.ascx"
    %>

<%@ MasterType VirtualPath="~/Site.Master" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<AndrewMoore:Weather id="MyWeather" runat="server"/>
</asp:Content>

					  

When the application is complete, you can select F5 to launch it from Visual Studio just like you would any other ASP.Net application. You'll see your application load on the Web site and then make requests to Facebook, which in turn will call back to your Web application and request the canvas, which is the Weather2.aspx code you created. This code executes on your Web site and returns HTML to Facebook as shown in Figure 1.

Figure 1. Your application executes and displays on Facebook.
Other  
  •  Writing Custom Facebook Applications - Creating Your Application with Visual Studio 2010
  •  Xen Virtualization : Installing Xen from Source
  •  Xen Virtualization : Installing Xen from Binary Packages
  •  Introducing IBM BPM and ESB : IBM SOA Reference Architecture & Introducing IBM WebSphere Process Server
  •  Introducing IBM BPM and ESB : Achieving success through BPM enabled by SOA
  •  Separating BPM and SOA Processes : Example-Process for Handling Credit Card Disputes
  •  Separating BPM and SOA Processes : The Model Stack & Design Tips on Separating BPM and SOA
  •  BizTalk 2006 : Editing and Resubmitting Suspended Messages (part 2) - Pseudo-Walkthrough to Perform Edits and Resubmits
  •  BizTalk 2006 : Editing and Resubmitting Suspended Messages (part 1)
  •  BizTalk 2006 : Building a Resequencing Aggregator
  •  
    Most View
    iStat Menus 4 for iPad
    Sony Vaio Pro 11 New High-End Ultrabook Review (Part 2)
    Using Google Apps On The Ipad Safari Browser
    Introducing Windows Presentation Foundation and XAML : Understanding The Syntax of WPF XAML (part 2)
    100 More Things Every Mac User Should Know (Part 4)
    Huawei Ascend G600 - I Wonder Why 600?
    Pre/ Power Amplifier - Nagra Jazz/ MSA (Part 2)
    ASRock Z77E-ITX - Great-Looking And Very Overclockable
    Microsoft Exchange Server 2010 : Managing Public Folder Settings (part 1) - Setting Client Permissions
    Midrange SSD Mayhem: Samsung And Corsair Go At It Once Again (Part 1)
    Top 10
    SQL Server 2012 : Consolidating Data Capture with SQLdiag - Getting Friendly with SQLdiag (part 2) - Using SQLdiag as a Service
    SQL Server 2012 : Consolidating Data Capture with SQLdiag - Getting Friendly with SQLdiag (part 1) - Using SQLdiag as a Command-line Application
    SQL Server 2012 : Consolidating Data Capture with SQLdiag - The Data Collection Dilemma, An Approach to Data Collection
    SQL Server 2012 : Troubleshooting Methodology and Practices - Data Analysis, Validating and Implementing Resolution
    SQL Server 2012 : Troubleshooting Methodology and Practices - Data Collection
    SQL Server 2012 : Troubleshooting Methodology and Practices - Defining the Problem
    SQL Server 2012 : Troubleshooting Methodology and Practices - Approaching Problems
    Windows 8 : Accessing System Image Backup and Recovery Functionality with Windows Backup, Cloud Backup
    Windows 8 : Using the Windows 8 Recovery Tools (part 2) - Push Button Reset
    Windows 8 : Using the Windows 8 Recovery Tools (part 1) - Creating a System Recovery Disc, Booting to the Windows Recovery Environment