.NET微信公众号开发之查询自定义菜单
一.前言
前面我们已经创建好了我们的自定义菜单。那么我们现在要如何查询我们自定义的菜单。
原理都是一样的,而且都是相当简单,只是接口地址文档换掉了。
二、开始编码
同样我们首先创建好我的查询页面,在这里我们使用aspx页面selectMenu.aspx
protectedvoidPage_Load(objectsender,EventArgse) { varstr=GetPage("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxd811f56f3&secret=76eb33f661296"); JObjectjo=JObject.Parse(str); access_token=jo["access_token"].ToString(); GetPage("https://api.weixin.qq.com/cgi-bin/menu/get?access_token="+access_token+""); //GetPage("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=access_token"); }
看代码是不是相当的简单。相信这对于聪明的你根本不是什么问题。同样删除我们的自定义菜单也很简单,只不过是接口地址换了而已,GetPage方法的代码前面的文章已经有了,在这里就不重复的说明了。
三、令牌优化.
前面我们已经知道了,怎么获取我们的access_token,我们知道它的有效时间是7200s,在这里难道我们每次请求都需要去重新获取一次,岂不是很麻烦,而且也不利于性能的优化,在这里我们对这个获取令牌的方法做一些优化,更有利于我们的代码.
在这里我们首先创建一个AccessToken类来存储我们的一些信息。代码如下
///<summary> ///微信许可令牌 ///</summary> publicclassAccessToken { ///<summary> ///保存已获取到的许可令牌,键为公众号,值为公众号最后一次获取到的令牌 ///</summary> privatestaticConcurrentDictionary<string,Tuple<AccessToken,DateTime>>accessTokens=newConcurrentDictionary<string,Tuple<AccessToken,DateTime>>(); ///<summary> ///获取accesstoken的地址 ///</summary> privateconststringurlForGettingAccessToken="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; ///<summary> ///获取accesstoken的http方法 ///</summary> privateconststringhttpMethodForGettingAccessToken=WebRequestMethods.Http.Get; ///<summary> ///保存accesstoken的最长时间(单位:秒),超过时间之后,需要重新获取 ///</summary> privateconstintaccessTokenSavingSeconds=7000; ///<summary> ///accesstoken ///</summary> publicstringaccess_token{get;set;} ///<summary> ///有效时间,单位:秒 ///</summary> publicintexpires_in{get;set;} ///<summary> ///构造函数 ///</summary> ///<paramname="_access_token">accesstoken</param> ///<paramname="_expires_in">有效时间</param> internalAccessToken(string_access_token,int_expires_in) { access_token=_access_token; expires_in=_expires_in; } ///<summary> ///返回AccessToken字符串 ///</summary> ///<returns></returns> publicoverridestringToString() { returnstring.Format("AccessToken:{0}\r\n有效时间:{1}秒",access_token,expires_in); } ///<summary> ///从JSON字符串解析AccessToken ///</summary> ///<paramname="json">JSON字符串</param> ///<returns>返回AccessToken</returns> internalstaticAccessTokenParseFromJson(stringjson) { varat=JsonConvert.DeserializeAnonymousType(json,new{access_token="",expires_in=1}); returnnewAccessToken(at.access_token,at.expires_in); } ///<summary> ///尝试从JSON字符串解析AccessToken ///</summary> ///<paramname="json">JSON字符串</param> ///<paramname="msg">如果解析成功,返回AccessToken;否则,返回null。</param> ///<returns>返回是否解析成功</returns> internalstaticboolTryParseFromJson(stringjson,outAccessTokentoken) { boolsuccess=false; token=null; try { token=ParseFromJson(json); success=true; } catch{} returnsuccess; } ///<summary> ///得到accesstoken ///</summary> ///<paramname="userName">公众号</param> ///<returns>返回accesstoken</returns> publicstaticAccessTokenGet(stringuserName) { Tuple<AccessToken,DateTime>lastToken=accessTokens.ContainsKey(userName)?accessTokens[userName]:null; AccessTokentoken=lastToken==null?null:lastToken.Item1; DateTimerefreshTime=lastToken==null?DateTime.MinValue:lastToken.Item2; doublems=(DateTime.Now-refreshTime).TotalSeconds; if(ms>accessTokenSavingSeconds||token==null) { //尝试从微信服务器获取2次 ErrorMessagemsg; AccessTokennewToken=GetFromWeixinServer(userName,outmsg); if(newToken==null) newToken=GetFromWeixinServer(userName,outmsg); if(newToken!=null) { lastToken=newTuple<AccessToken,DateTime>(newToken,DateTime.Now); accessTokens[userName]=lastToken; token=newToken; } } returntoken; } ///<summary> ///从微信服务器获取accesstoken ///</summary> ///<paramname="userName">公众号</param> ///<paramname="msg">从服务器返回的错误信息。</param> ///<returns>返回许可令牌;如果获取失败,返回null。</returns> privatestaticAccessTokenGetFromWeixinServer(stringuserName,outErrorMessagemsg) { AccessTokentoken=null; msg=newErrorMessage(ErrorMessage.ExceptionCode,""); stringurl=string.Format(urlForGettingAccessToken,WxPayConfig.APPID,WxPayConfig.APPSECRET); stringresult; if(!HttpHelper.Request(url,outresult,httpMethodForGettingAccessToken,string.Empty)) { msg.errmsg="从微信服务器获取响应失败。"; returntoken; } if(ErrorMessage.IsErrorMessage(result)) msg=ErrorMessage.Parse(result); else { try { token=AccessToken.ParseFromJson(result); } catch(Exceptione) { msg=newErrorMessage(e); } } returntoken; } }
从这个类中的代码我们看到,每次获取access_token的时候都会判断一些时间是不是超过了7000,我们的token过期时间是7200s,这样就不需要每次请求的时候都是重新获取token。
这个时候我们的查询代码可以优化下.
protectedvoidPage_Load(objectsender,EventArgse) { stringusername=System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString(); AccessTokentoken=AccessToken.Get(username);
GetPage("https://api.weixin.qq.com/cgi-bin/menu/get?access_token="+access_token+""); //GetPage("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=access_token"); }