2012年10月17日 星期三

Facebook ashx 與網頁的結構安排

因為網頁的載入效能不佳,經檢查是在Facebook取得使用者資訊的速度太慢,而之前系統是再每一頁都會透過以下程式去取得使用者資訊,因此必須要做改良,避免重複取得
                    var client = new FacebookClient(accessToken);                   
                    dynamic me = client.Get("me");

現在調整成只在site.master去取得Facebook的tooken並且寫入在Cookie中,這樣可以省略每一頁都要重新取得,加速網頁載入速度,不過原本的想法是每一頁只要取得Cookie即可,可以省略以下程式碼,但實做後發現不行,因為內頁的PageLoad早於MasterPage的PageLoad,因此如果使用者Cookie不存在時,如果沒有在內頁的PageLoad就直接連接Facebook去取得資訊,而把他return掉,則跑到MasterPage去取得後,會造成如果內頁的PageLoad在取得使用資訊後要做一些事情,會變成後面的程式無法正常執行,因此,還是要在內頁加上去直接連接Facebook取得使用者資訊的程式碼

        if (Session["AccessToken"] != null)
        {
            try
            {
                string[] UserData = (HttpContext.Current.User.Identity.Name.Split('-'));
                FBID = UserData[0];
                CName = UserData[1];
                UserID = UserData[2];
            }
            catch
            {
                try
                {
                    var accessToken = Session["AccessToken"].ToString();
                    var client = new FacebookClient(accessToken);                   
                    dynamic me = client.Get("me");
                    FBID = me.id;
                    CName = me.name;
                    EMail = me.email;
                    Birthday = me.birthday;
                    Gender = me.gender;
                    UserName = me.username;
                    Locale = me.locale;
                }
                catch (Exception ex)
                {
                    Session.Remove("AccessToken");
                    mdlPopup.Show();
                    //return;
                }
            }
        }

原本的想法是這樣

        if (Session["AccessToken"] != null)
        {
            try
            {
                string[] UserData = (HttpContext.Current.User.Identity.Name.Split('-'));
                FBID = UserData[0];
                //CName = UserData[1];
                UserID = UserData[2];
            }
            catch (Exception ex)
            {
                lblMsg.Text = "請先登入";
                Session.Remove("AccessToken");
                return;
            }
        }
        else
        {
            lblMsg.Text = "請先登入";
            Session.Remove("AccessToken");
            return;
        }

原本ashx都只是導向index.aspx,因此index.aspx會處理cookie跟tooken的資料,不過這種作法不好,因為如果使用者經由別人所提供的內頁網址要進入網站時,都會被重新導向index.aspx,必須在登入後,再重貼一次網址才能真正進入該網址,除非他第一次貼上網址時就已經是登入狀態,這樣使用上有些不便利

因此我將ashx的導向改為以HTTP_REFERER去回導回原本的頁面,但這樣問題就來了,回導頁面的page_load事件會比master的page_load事件更早,因此如果此時沒有取得使用者的資料,就可能發生錯誤,因此我們還是得去完整的處理tooken與cookie
        if (Session["AccessToken"] != null)
        {
            try
            {
                string[] UserData = (HttpContext.Current.User.Identity.Name.Split('-'));
                MyFBID = UserData[0];
                CName = UserData[1];
                UserID = UserData[2];
            }
            catch
            {
                try
                {
                    var accessToken = Session["AccessToken"].ToString();
                    var client = new FacebookClient(accessToken);
                    dynamic me = client.Get("me");
                    MyFBID = me.id;
                    CName = me.name;
                    SQLStr = "select * from Users where FBID=@FBID ";
                    dr = zDBUtils.GetDataRow(ref SQLStr, "FBID", MyFBID);
                    if (dr != null)
                    {
                        UserID = dr["ID"].ToString();
                    }
                    System.Web.Security.FormsAuthentication.SetAuthCookie(MyFBID + "-" + CName + "-" + UserID, false);
                    HttpCookie aCookie = new HttpCookie("xxx");
                    aCookie.Expires = DateTime.Now.AddDays(-1);
                    Response.Cookies.Add(aCookie);
                }
                catch (Exception ex)
                {
                    lblMsg.Text = "請先登入";
                    //Session.Remove("AccessToken");                   
                    return;
                }
            }
        }
        else
        {
            lblMsg.Text = "請先登入";
            //Session.Remove("AccessToken");
            return;
        }


因為我們在內頁,masterpage已經有做先讀取cookie的判斷,因此最多也只是要導的頁面去連一次facebook取得資料,而sitemaster就只要讀取cookie即可

沒有留言:

張貼留言