一.前言
前面我們已經(jīng)創(chuàng)建好了我們的自定義菜單。那么我們現(xiàn)在要如何查詢我們自定義的菜單。
原理都是一樣的,而且都是相當(dāng)簡單,只是接口地址文檔換掉了。
二、開始編碼
同樣我們首先創(chuàng)建好我的查詢頁面,在這里我們使用aspx頁面 selectMenu.aspx
protected void Page_Load(object sender, EventArgs e)
{
var str = GetPage("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxd811f56f3&secret=76eb33f661296");
JObject jo = 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");
}
看代碼是不是相當(dāng)?shù)暮唵巍O嘈胚@對于聰明的你根本不是什么問題。同樣刪除我們的自定義菜單也很簡單,只不過是接口地址換了而已,GetPage方法的代碼前面的文章已經(jīng)有了,在這里就不重復(fù)的說明了。
三、令牌優(yōu)化.
前面我們已經(jīng)知道了,怎么獲取我們的access_token,我們知道它的有效時(shí)間是7200s,在這里難道我們每次請求都需要去重新獲取一次,豈不是很麻煩,而且也不利于性能的優(yōu)化,在這里我們對這個(gè)獲取令牌的方法做一些優(yōu)化,更有利于我們的代碼.
在這里我們首先創(chuàng)建一個(gè)AccessToken類來存儲我們的一些信息。代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/// <summary> /// 微信許可令牌 /// </summary> public class AccessToken { /// <summary> /// 保存已獲取到的許可令牌,鍵為公眾號,值為公眾號最后一次獲取到的令牌 /// </summary> private static ConcurrentDictionary< string , Tuple<AccessToken, DateTime>> accessTokens = new ConcurrentDictionary< string , Tuple<AccessToken, DateTime>>(); /// <summary> /// 獲取access token的地址 /// </summary> private const string urlForGettingAccessToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}" ; /// <summary> /// 獲取access token的http方法 /// </summary> private const string httpMethodForGettingAccessToken = WebRequestMethods.Http.Get; /// <summary> /// 保存access token的最長時(shí)間(單位:秒),超過時(shí)間之后,需要重新獲取 /// </summary> private const int accessTokenSavingSeconds = 7000; /// <summary> /// access token /// </summary> public string access_token { get ; set ; } /// <summary> /// 有效時(shí)間,單位:秒 /// </summary> public int expires_in { get ; set ; } /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="_access_token">access token</param> /// <param name="_expires_in">有效時(shí)間</param> internal AccessToken( string _access_token, int _expires_in) { access_token = _access_token; expires_in = _expires_in; } /// <summary> /// 返回AccessToken字符串 /// </summary> /// <returns></returns> public override string ToString() { return string .Format( "AccessToken:{0}\r\n有效時(shí)間:{1}秒" , access_token, expires_in); } /// <summary> /// 從JSON字符串解析AccessToken /// </summary> /// <param name="json">JSON字符串</param> /// <returns>返回AccessToken</returns> internal static AccessToken ParseFromJson( string json) { var at = JsonConvert.DeserializeAnonymousType(json, new { access_token = "" , expires_in = 1 }); return new AccessToken(at.access_token, at.expires_in); } /// <summary> /// 嘗試從JSON字符串解析AccessToken /// </summary> /// <param name="json">JSON字符串</param> /// <param name="msg">如果解析成功,返回AccessToken;否則,返回null。</param> /// <returns>返回是否解析成功</returns> internal static bool TryParseFromJson( string json, out AccessToken token) { bool success = false ; token = null ; try { token = ParseFromJson(json); success = true ; } catch { } return success; } /// <summary> /// 得到access token /// </summary> /// <param name="userName">公眾號</param> /// <returns>返回access token</returns> public static AccessToken Get( string userName) { Tuple<AccessToken, DateTime> lastToken = accessTokens.ContainsKey(userName) ? accessTokens[userName] : null ; AccessToken token = lastToken == null ? null : lastToken.Item1; DateTime refreshTime = lastToken == null ? DateTime.MinValue : lastToken.Item2; double ms = (DateTime.Now - refreshTime).TotalSeconds; if (ms > accessTokenSavingSeconds || token == null ) { //嘗試從微信服務(wù)器獲取2次 ErrorMessage msg; AccessToken newToken = GetFromWeixinServer(userName, out msg); if (newToken == null ) newToken = GetFromWeixinServer(userName, out msg); if (newToken != null ) { lastToken = new Tuple<AccessToken, DateTime>(newToken, DateTime.Now); accessTokens[userName] = lastToken; token = newToken; } } return token; } /// <summary> /// 從微信服務(wù)器獲取access token /// </summary> /// <param name="userName">公眾號</param> /// <param name="msg">從服務(wù)器返回的錯(cuò)誤信息。</param> /// <returns>返回許可令牌;如果獲取失敗,返回null。</returns> private static AccessToken GetFromWeixinServer( string userName, out ErrorMessage msg) { AccessToken token = null ; msg = new ErrorMessage(ErrorMessage.ExceptionCode, "" ); string url = string .Format(urlForGettingAccessToken, WxPayConfig.APPID, WxPayConfig.APPSECRET); string result; if (!HttpHelper.Request(url, out result, httpMethodForGettingAccessToken, string .Empty)) { msg.errmsg = "從微信服務(wù)器獲取響應(yīng)失敗。" ; return token; } if (ErrorMessage.IsErrorMessage(result)) msg = ErrorMessage.Parse(result); else { try { token = AccessToken.ParseFromJson(result); } catch (Exception e) { msg = new ErrorMessage(e); } } return token; } } |
從這個(gè)類中的代碼我們看到,每次獲取access_token的時(shí)候都會判斷一些時(shí)間是不是超過了7000,我們的token過期時(shí)間是7200s,這樣就不需要每次請求的時(shí)候都是重新獲取token。
這個(gè)時(shí)候我們的查詢代碼可以優(yōu)化下.
protected void Page_Load(object sender, EventArgs e)
{
string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
AccessToken token = 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");
}
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。