天天看點

WebApi系列~QQ互聯的引入(QConnectSDK)

回到目錄

感謝與改進

首先要感謝張善友老兄為大家封裝的這個DLL,它将QQ官方的相關API都內建到了這個裡面,這對于開發人員來說,是個福音,有人會說,為什麼QQ官方沒有提供.net版的SDK呢,在這裡,我想說,可能是騰訊公司沒有人會.net吧,哈哈!

玩笑話,在使用善友兄的QConnectSDK時,也遇到了一些問題,如session持久化問題,有人會說,session可以持久化所有對象,當然,這句話在某種情況下是正确的,但當你的session持久化方式改變後,如,使用sqlserver來存儲資訊時(可能是為了跨站點進行資訊共享吧,呵呵)你的session就不允許使用無法序列化的對象或 MarshalByRef 對象.這是個很嚴重的問題,在我今天介紹的架構裡,解決了它,主要思想是使用sessionID和cache來代替session來存儲某些對象的.

插件DLL

Newtonsoft.Json.dll

QConnectSDK.dll

RestSharp.dll

DLL下載下傳

注意,它們之前是互相依賴的,是以,要考慮到版本的相容性

代碼相關

C#代碼

     /// <summary>
        /// QQ登陸頁面
        /// </summary>
        [HttpGet]
        public ActionResult QQLogin(string returnUrl)
        {
            if (!string.IsNullOrWhiteSpace(returnUrl))
            {
                System.Web.HttpRuntime.Cache.Insert(Session.SessionID + "RETURNURL", returnUrl);
            }
            var context = new QzoneContext();
            string state = Guid.NewGuid().ToString().Replace("-", "");
            System.Web.HttpRuntime.Cache.Insert(Session.SessionID + "requeststate", state);//一個請求狀态碼,寫入session,在redirectUri時進行比較
            string scope = "get_user_info,add_share,list_album,upload_pic,check_page_fans,
                add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,
                get_fanslist,get_idolist,add_idol,del_idol,add_one_blog,add_topic,get_tenpay_addr";
            var authenticationUrl = context.GetAuthorizationUrl(state, scope);
            return new RedirectResult(authenticationUrl);

        }

        /// <summary>
        /// 回調頁面
        /// </summary>
        public ActionResult QQConnect()
        {
            if (Request.Params["code"] != null)
            {
                QOpenClient qzone = null;
                string url = Url.Action("index", "home");
                var verifier = Request.Params["code"];
                var state = Request.Params["state"];
                System.Web.HttpRuntime.Cache.Insert(Session.SessionID + "verifier", verifier);
                string requestState = System.Web.HttpRuntime.Cache.Get(Session.SessionID + "requeststate").ToString();

                if (state == requestState)
                {
                    qzone = new QOpenClient(verifier, state);
                    var currentUser = qzone.GetCurrentUser();
                    if (System.Web.HttpRuntime.Cache.Get(Session.SessionID + "QzoneOauth") == null)
                    {
                        System.Web.HttpRuntime.Cache.Insert(Session.SessionID + "QzoneOauth", qzone);
                    }
                    if (!string.IsNullOrWhiteSpace((System.Web.HttpRuntime.Cache.Get(Session.SessionID + "RETURNURL") ?? string.Empty).ToString()))
                    {
                        url = System.Web.HttpRuntime.Cache.Get(Session.SessionID + "RETURNURL").ToString();
                    }
                    ViewBag.friendlyName = currentUser.Nickname;
                    ViewBag.img = currentUser.Figureurl;

                }

            }
            return View();
        }      

HTML & JS代碼

<h2><a id="logins">qq</a></h2>
<h1>@Request.QueryString["friendlyName"]</h1>
<img  src="@Request.QueryString["img"]"/>

<script type="text/ecmascript">
    $(function () {
        $("#logins").live("click", function () {
            window.open('/Home/QQLogin', 'newwindow', 'height=400,width=400,top=400,left=400,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no');
        });
    });
</script>      

程式截圖

改進的地方

這個程式事實上也是有問題的,因應當有多台WEB伺服器作負載均衡時,它的session_ID也是不同的,這時,就會出現問題了,是以,最好還是使用session來做這事,我試着把複雜對象的存儲去掉了,QQ登陸也是可以的,不知道善友用這個持久化幹什麼用的.

修改後的代碼如下

/// <summary>
        /// QQ登陸頁面
        /// </summary>
        [HttpGet]
        public ActionResult QQLogin(string returnUrl)
        {
            if (!string.IsNullOrWhiteSpace(returnUrl))
            {
                Session["RETURNURL"] = returnUrl;
            }
            var context = new QzoneContext();
            string state = Guid.NewGuid().ToString().Replace("-", "");
            Session["requeststate"] = state;//一個請求狀态碼,寫入session,在redirectUri時進行比較
            string scope = "get_user_info,add_share,list_album,upload_pic,check_page_fans,add_t,
                            add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,
                            get_idolist,add_idol,del_idol,add_one_blog,add_topic,get_tenpay_addr";
            var authenticationUrl = context.GetAuthorizationUrl(state, scope);
            return new RedirectResult(authenticationUrl);

        }

        /// <summary>
        /// 回調頁面
        /// </summary>
        public ActionResult QQConnect()
        {
            if (Request.Params["code"] != null)
            {
                QOpenClient qzone = null;
                string url = Url.Action("index", "home");
                var verifier = Request.Params["code"];
                var state = Request.Params["state"];
                Session["verifier"] = verifier;
                string requestState = Session["requeststate"].ToString();

                if (state == requestState)
                {
                    qzone = new QOpenClient(verifier, state);
                    var currentUser = qzone.GetCurrentUser();
                    //  Session["QzoneOauth"] = qzone; //不支援session持久化sqlserver方法
                    if (!string.IsNullOrWhiteSpace((Session["RETURNURL"] ?? string.Empty).ToString()))
                    {
                        url = Session["RETURNURL"].ToString();
                    }
                    ViewBag.friendlyName = currentUser.Nickname;
                    ViewBag.img = currentUser.Figureurl;

                }

            }
            return View();
        }      

作者:倉儲大叔,張占嶺,

榮譽:微軟MVP

QQ:853066980

支付寶掃一掃,為大叔打賞!

WebApi系列~QQ互聯的引入(QConnectSDK)