.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"); }