回到目录
感谢与改进
首先要感谢张善友老兄为大家封装的这个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
支付宝扫一扫,为大叔打赏!
