WeixinApi.cs
12.3 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Web;
using Quiz.Utility;
namespace Quiz.SiteBase
{
public class WeixinApi
{
static Dictionary<string, WeixinAccount> Cache = new Dictionary<string, WeixinAccount>();
public static string oauthurl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
public static string oauthuserinfourl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
public static string wapurl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";
public static string userinfourl = "https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN";
public static WeixinAccount GetWeixinAccount(string actid)
{
if (!Cache.ContainsKey(actid))
{
List<Models.Weixin> wxList = SiteBase.Cache.CacheManage.Weixin.CacheData;
if (wxList == null) return null;
Models.Weixin wxaccount = wxList.Find(o => o.ActId == actid);
//appid等没的话不缓存 account,为了不获取token ticket
if (wxaccount == null || string.IsNullOrEmpty(wxaccount.AppId) || string.IsNullOrEmpty(wxaccount.AppSecret)) return null;
WeixinAccount account = new WeixinAccount(actid, wxaccount.AppId, wxaccount.AppSecret);
account.TokenRefresh += AccountOnTokenRefresh;
Cache.Add(actid, account);
}
return Cache[actid];
}
private static void AccountOnTokenRefresh(string actid)
{
List<Models.Weixin> wxList = SiteBase.Cache.CacheManage.Weixin.CacheData;
Models.Weixin wxaccount = wxList.Find(o => o.ActId == actid);
if (wxaccount == null || string.IsNullOrEmpty(wxaccount.AppId) || string.IsNullOrEmpty(wxaccount.AppSecret)) Cache.Remove(actid);
else if (Cache.ContainsKey(actid)) Cache[actid].Update(wxaccount.AppId, wxaccount.AppSecret);
}
public static string GetToken(string actid)
{
try
{
WeixinAccount account = GetWeixinAccount(actid);//缓存的公众号信息
//返回Token
return account == null ? "" : account.AccessToken;
}
catch (Exception err)
{
return "";
}
}
public static string GetJsapiTicket(string actid)
{
WeixinAccount account = GetWeixinAccount(actid);//缓存的公众号信息
return account == null ? "" : account.JsapiTicket;
}
}
#region 微信公众号信息
public delegate void AccessTokenCallback(string actid);
/// <summary>
/// 微信公众号信息
/// </summary>
public class WeixinAccount
{
static WeiXinAction action = new WeiXinAction();
private string app_secret;
private string jsapi_ticket;
private string access_token;
/// <summary>
/// jsapi_ticket到期时间
/// </summary>
private DateTime jsapi_ticket_time;
/// <summary>
/// access_token到期时间
/// </summary>
private DateTime access_token_time;
public string Id { get; private set; }
/// <summary>
/// 公众号AppID
/// </summary>
public string AppId { get; private set; }
/// <summary>
/// jsapi_ticket, 有效期为7200秒
/// </summary>
public string JsapiTicket
{
get
{
if (jsapi_ticket_time < DateTime.Now)
{
var ticket = action.GetJsapiTicket(AccessToken, jsapi_ticket_time);
if (ticket == null || ticket.errcode != 0) return string.Empty;
jsapi_ticket = ticket.ticket;
jsapi_ticket_time = DateTime.Now.AddSeconds(ticket.expires_in);
}
return jsapi_ticket;
}
}
/// <summary>
/// access_token, 有效期7200秒
/// </summary>
public string AccessToken
{
get
{
if (access_token_time < DateTime.Now)
{
OnTokenRefresh(Id);
var token = action.GetToken(AppId, app_secret, access_token_time);
if (token == null) return string.Empty;
access_token = token.access_token;
access_token_time = DateTime.Now.AddSeconds(int.Parse(token.expires_in));
}
return access_token;
}
}
/// <summary>
/// 实例化微信公众号
/// </summary>
/// <param name="id"></param>
/// <param name="appid"></param>
/// <param name="secret"></param>
public WeixinAccount(string id, string appid, string secret)
{
Id = id;
AppId = appid;
app_secret = secret;
access_token_time = DateTime.Parse("1970-01-01");
jsapi_ticket_time = DateTime.Parse("1970-01-01");
}
public event AccessTokenCallback TokenRefresh;
protected virtual void OnTokenRefresh(string actid)
{
var handler = TokenRefresh;
if (handler != null) handler(actid);
}
public void Update(string appid, string secret)
{
if (AppId != null || app_secret != secret)
{
AppId = appid;
app_secret = secret;
access_token_time = DateTime.Parse("1970-01-01");
jsapi_ticket_time = DateTime.Parse("1970-01-01");
}
}
}
#endregion
#region 获取token和jsticket
public class WeiXinAction
{
/// <summary>
/// 获得Token
/// </summary>
/// <param name="appid"></param>
/// <param name="secret"></param>
/// <param name="YouXRQ">token到期时间,获取的时间+7200</param>
/// <returns>过期了返回新的Access_Token,否则返回空</returns>
public Access_Token GetToken(string appid, string secret, DateTime YouXRQ)
{
if (DateTime.Now > YouXRQ) //过期
{
string Str = GetJson(string.Format(new WeiUrlConfig().URL_GetToken, appid, secret));
return JsonHelper.ParseFromJson<Access_Token>(Str);
}
return null;
}
/// <summary>
/// 获得JsapiTicket
/// </summary>
/// <param name="token"></param>
/// <param name="YouXRQ"></param>
/// <returns></returns>
public JsapiTicket GetJsapiTicket(string token, DateTime YouXRQ)
{
if (DateTime.Now > YouXRQ) //过期
{
string Str = GetJson(string.Format(new WeiUrlConfig().URL_GetJsapiTicket, token));
return JsonHelper.ParseFromJson<JsapiTicket>(Str);
}
return null;
}
private string GetJson(string url)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; //SSL3协议替换成TLS协议
WebClient wc = new WebClient();
wc.Credentials = CredentialCache.DefaultCredentials;
wc.Encoding = Encoding.UTF8;
string returnText = wc.DownloadString(url);
if (returnText.Contains("errcode"))
{
//可能发生错误
}
return returnText;
}
}
#endregion
#region 授权类型
public class OAuth_Token
{
public OAuth_Token()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
//access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
//expires_in access_token接口调用凭证超时时间,单位(秒)
//refresh_token 用户刷新access_token
//openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
//scope 用户授权的作用域,使用逗号(,)分隔
public string access_token { get; set; }
public string expires_in { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
}
public class Access_Token
{
public string access_token { get; set; }
public string expires_in { get; set; }
}
public class Ticket
{
public string ticket { get; set; }
public string expire_seconds { get; set; }
}
public class JsapiTicket
{
public int errcode { get; set; }
public string errmsg { get; set; }
public string ticket { get; set; }
public int expires_in { get; set; }
}
#endregion
#region 配置信息
public class WeiUrlConfig
{
public string URL_GetToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
public string URL_GetJsapiTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
public string URL_User_ALL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}&next_openid={1}";
public string URL_User_One = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN";
public string URL_User_GroupCreate = "https://api.weixin.qq.com/cgi-bin/groups/create?access_token={0}";
public string URL_User_GroupALL = "https://api.weixin.qq.com/cgi-bin/groups/get?access_token={0}";
public string URL_User_GroupIDGet = "https://api.weixin.qq.com/cgi-bin/groups/getid?access_token={0}";
public string URL_User_GroupUpdate = "https://api.weixin.qq.com/cgi-bin/groups/update?access_token={0}";
public string URL_User_GroupMove = "https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token={0}";
public string URL_Menu_Greate = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";
public string URL_Menu_Get = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}";
public string URL_Menu_Delete = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}";
public string URL_GetTicket = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}";
public string URL_GetD2Image = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}";
public string URL_GetFile = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}";
public string URL_UploadFile = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}";
public string URL_UpVideo = "https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token={0}";
//群发 上传图文
public string URL_SendAllByGroup = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}";
public string URL_SendAllByOpenid = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}";
public string URL_UploadArticle = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={0}";
public string URL_DeleteSendALL = "https://api.weixin.qq.com//cgi-bin/message/mass/delete?access_token={0}";
//48小时内发送客服消息
public string URL_SendMSG = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}";
//聊天记录
public string URL_GetChatLog = "https://api.weixin.qq.com/cgi-bin/customservice/getrecord?access_token={0}";
}
#endregion
}