微信公众号开发C#帮助类-非全部完善

  1 using House.IService.Common;
  2 using House.IService.Common.Sign;
  3 using House.IService.Model;
  4 using Microsoft.AspNetCore.Http;
  5 using Newtonsoft.Json;
  6 using System;
  7 using System.Collections.Generic;
  8 using System.Data;
  9 using System.IO;
 10 using System.Linq;
 11 using System.Net;
 12 using System.Security.Cryptography;
 13 using System.Text;
 14 using System.Threading.Tasks;
 15 using Config = Data.MSSQL.Common;
 16 
 17 namespace House.Service.Common
 18 {
 19     /// <summary>
 20     /// 后续常量规范化,待修改[标记]
 21     /// </summary>
 22     public class WinXinSingle : IWeiXinSingle
 23     {
 24         private IHttpContextAccessor _httpContext = null;
 25         private ISignSingle _sign = null;
 26         private string AppId => CommonFiled.appID;
 27         private string AppSecret => CommonFiled.appSecret;
 28 
 29         public WinXinSingle(IHttpContextAccessor http, ISignSingle sign)
 30         {
 31             this._httpContext = http;
 32             this._sign = sign;
 33         }
 34 
 35         #region Private 
 36         private Microsoft.AspNetCore.Http.HttpContext Current
 37         {
 38             get
 39             {
 40                 return _httpContext.HttpContext;
 41             }
 42         }
 43 
 44         private string ParamsQuery(string param)
 45         {
 46             return this._httpContext.HttpContext.Request.Query[param].FirstOrDefault();
 47         }
 48 
 49         #region Session 操作
 50         public string GetSession(string key)
 51         {
 52             byte[] value = null;
 53             if (this._httpContext.HttpContext.Session.TryGetValue(key, out value))
 54             {
 55                 return System.Text.Encoding.Default.GetString(value);
 56             }
 57             return null;
 58         }
 59 
 60         /// <summary>
 61         /// 已经修改其他的授权方式,Session已经不需要了。暂时弃用
 62         /// </summary>
 63         /// <param name="key"></param>
 64         /// <param name="val"></param>
 65         [Obsolete]
 66         public void SetSession(string key, string val)
 67         {
 68             byte[] value = System.Text.Encoding.Default.GetBytes(val);
 69             this._httpContext.HttpContext.Session.Set(key, value);
 70         }
 71         #endregion
 72 
 73         #endregion
 74 
 75 
 76         public async Task<string> CheckServer()
 77         {
 78             //1 自己的服务器代码接受微信提交过来的4个参数
 79             string token =  CommonFiled.token;
 80             string signature = ParamsQuery("signature");
 81             string timestamp = ParamsQuery("timestamp");
 82             string nonce = ParamsQuery("nonce");
 83             string echostr = ParamsQuery("echostr");
 84             string[] temp = { token, timestamp, nonce };
 85             //字典排序
 86             Array.Sort(temp);
 87             //3个参数拼接成一个字符串
 88             string temp1 = string.Join("", temp);
 89             //字符串进行sha1加密
 90             string code = this._sign.Sha1(temp1);
 91             if (code.ToLower().Equals(signature))
 92             {
 93                 //比较一致,表示通过微信的效验了,返回echostr字符串
 94                 return echostr;
 95             }
 96             else
 97             {
 98                 return "Authorization failed:" + echostr;
 99             }
100         }
101 
102         /// <summary>
103         /// 获取普通的access_token
104         /// </summary>
105         /// <returns></returns>
106         public AccessToken GetAccessToken()
107         {
108             AccessToken token = new AccessToken();
109             if (token.access_token == null)
110             {
111                 //请求微信服务器得到accessToken
112                 string url = string.Format(@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",
113                     AppId, AppSecret);
114                 string access_token = SendGet(url);
115                 return JsonConvert.DeserializeObject<AccessToken>(access_token);
116             }
117             return token;
118         }
119 
120         public string GetCodeUrl(string url)
121         {
122             //对url进行编码
123             url = System.Web.HttpUtility.UrlEncode(url);
124             string CodeUrl = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + AppId
125                   + "&redirect_uri=" + url + "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect");
126             return CodeUrl;
127         }
128 
129         public string GetCurrentFullHost() => _httpContext.HttpContext.Request.Host.Value;
130 
131         public string GetOpenId()
132         {
133             string openid = "";
134             var host1 = _httpContext.HttpContext.Request.Host.Value;
135             var host = CommonFiled.DomainURL;
136             string url = host + _httpContext.HttpContext.Request.Path.Value;
137             //先要判断是否是获取code后跳转过来的
138             string code = ParamsQuery("code");
139             if (string.IsNullOrEmpty(code))
140             {
141                 //Code为空时,先获取Code
142                 string GetCodeUrls = GetCodeUrl(url);
143                 _httpContext.HttpContext.Response.Redirect(GetCodeUrls);//先跳转到微信的服务器,取得code后会跳回来这页面的
144             }
145             else
146             {
147                 string Code = ParamsQuery("code");
148                 openid = GetOauthAccessOpenId(Code)?.openid;//重新取得用户的openid
149                                                             //SetSession("OpenId", Code);
150             }
151             return openid;
152         }
153 
154         public string GetOpenId(out string redUrl)
155         {
156             redUrl = "";
157             string openid = "";
158             var host1 = _httpContext.HttpContext.Request.Host.Value;
159             var host = CommonFiled.DomainURL; 
160             string url = host + _httpContext.HttpContext.Request.Path.Value;
161             //先要判断是否是获取code后跳转过来的
162             string code = ParamsQuery("code");
163             if (string.IsNullOrEmpty(code))
164             {
165                 //Code为空时,先获取Code
166                 redUrl = GetCodeUrl(url);
167                 //_httpContext.HttpContext.Response.Redirect(GetCodeUrls);//先跳转到微信的服务器,取得code后会跳回来这页面的
168             }
169             else
170             {
171                 string Code = ParamsQuery("code");
172                 openid = GetOauthAccessOpenId(Code)?.openid;//重新取得用户的openid
173                                                             //SetSession("OpenId", Code);
174             }
175             return openid;
176         }
177 
178         /// <summary>
179         /// 通过code换取网页授权access_token
180         /// </summary>
181         /// <param name="code"></param>
182         /// <returns></returns>
183         public OAuthToken GetOauthAccessOpenId(string code)
184         {
185             string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + AppId + "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
186             string access_token = SendGet(url);
187             OAuthToken ac = JsonConvert.DeserializeObject<OAuthToken>(access_token);
188             return ac;
189         }
190 
191 
192         public string GetRawUrl()
193         {
194             return string.Format("http://{0}{1}", GetCurrentFullHost(), _httpContext.HttpContext.Request.PathBase);
195         }
196 
197         public int GetTime()
198         {
199 
200             DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
201             return (int)(DateTime.Now - dateStart).TotalSeconds;
202         }
203 
204         public void MusicMessage(string touserName, string formUserName, string title, string remark, string url)
205         {
206             string msg = string.Format(@"<xml>
207                                         <ToUserName><![CDATA[{0}]]></ToUserName>
208                                         <FromUserName><![CDATA[{1}]]></FromUserName>
209                                         <CreateTime>{2}</CreateTime>
210                                         <MsgType><![CDATA[music]]></MsgType>
211                                         <Music>
212                                         <Title><![CDATA[{3}]]></Title>
213                                         <Description><![CDATA[{4}]]></Description>
214                                         <MusicUrl><![CDATA[{5}]]></MusicUrl>
215                                         <HQMusicUrl><![CDATA[{5}]]></HQMusicUrl>
216                                         </Music>
217                                         </xml>", formUserName, touserName, GetTime(), title, remark, url);
218             _httpContext.HttpContext.Response.WriteAsync(msg); // 如果需要同步这里再修改
219         }
220 
221         public void NewsMessage(string tosuerName, string fromUserName, DataTable dt)
222         {
223             StringBuilder sb = new StringBuilder();
224             for (int i = 0; i < dt.Rows.Count; i++)
225             {
226                 sb.AppendFormat(@"<item>
227                                         <Title><![CDATA[{0}]]></Title>
228                                         <Description><![CDATA[{1}]]></Description>
229                                         <PicUrl><![CDATA[{2}]]></PicUrl>
230                                         <Url><![CDATA[{3}]]></Url>
231                                         </item>", dt.Rows[i]["Title"].ToString(), dt.Rows[i]["Remark"].ToString(), dt.Rows[i]["PicUrl"].ToString(), dt.Rows[i]["Url"].ToString());
232             }
233             string msg = string.Format(@"<xml>
234                                         <ToUserName><![CDATA[{0}]]></ToUserName>
235                                         <FromUserName><![CDATA[{1}]]></FromUserName>
236                                         <CreateTime>{2}</CreateTime>
237                                         <MsgType><![CDATA[news]]></MsgType>
238                                         <ArticleCount>{4}</ArticleCount>
239                                         <Articles>
240                                           {3}
241                                         </Articles>
242                                         </xml> ", fromUserName, tosuerName, GetTime(), sb.ToString(), dt.Rows.Count);
243             _httpContext.HttpContext.Response.WriteAsync(msg);
244         }
245 
246         public string SendGet(string url)
247         {
248             //模拟一个浏览器的请求
249             //1.创建一个请求对象
250             WebRequest request = WebRequest.Create(url);
251             request.Method = "GET";
252             request.ContentType = "applicatoin/x-www/form-urlencoded";
253             string str = null;//保存请求服务器以后返回的结果
254             //得到 响应的内容
255             WebResponse response = request.GetResponse();
256             if (response != null)
257             {
258                 using (Stream stream = response.GetResponseStream())
259                 {
260                     using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
261                     {
262                         str = reader.ReadToEnd();
263                     }
264                 }
265             }
266             return str;
267         }
268 
269         public string SendPost(string url, string requestData)
270         {
271             WebRequest request = WebRequest.Create(url);
272             request.Method = "POST";
273             byte[] postDatas = null;
274             request.ContentType = "application/x-www-form-urlencoded";
275             postDatas = Encoding.UTF8.GetBytes(requestData);
276             request.ContentLength = postDatas.Length;
277             using (Stream stream = request.GetRequestStream())
278             {
279                 stream.Write(postDatas, 0, postDatas.Length);
280             }
281             string responseData = null;//服务器响应的数据
282             WebResponse response = request.GetResponse();
283             if (response != null)
284             {
285                 using (Stream st = response.GetResponseStream())
286                 {
287                     using (StreamReader reader = new StreamReader(st, Encoding.UTF8))
288                     {
289                         responseData = reader.ReadToEnd();
290                     }
291                 }
292             }
293             return responseData;
294         }
295 
296         public void TextMessage(string toUserName, string formUserName, string content)
297         {
298             string msg = string.Format(@"<xml>
299                                         <ToUserName><![CDATA[{0}]]></ToUserName>
300                                         <FromUserName><![CDATA[{1}]]></FromUserName>
301                                         <CreateTime>{2}</CreateTime>
302                                         <MsgType><![CDATA[text]]></MsgType>
303                                         <Content><![CDATA[{3}]]></Content>
304                                         </xml>", formUserName, toUserName, GetTime(), content);
305             _httpContext.HttpContext.Response.WriteAsync(msg);
306         }
307 
308         /// <summary>
309         /// 获取签名用于JS-SDK的调用
310         ///出于安全考虑,开发者必须在服务器端实现签名的逻辑。   
311         /// </summary>
312         public string GetJsApiSign(string noncestr, string jsapi_ticket, string timestamp, string url)
313         {
314             //将字段添加到列表中。
315             string[] arr = new[]
316             {
317                 string.Format("noncestr={0}",noncestr),
318                 string.Format("jsapi_ticket={0}",jsapi_ticket),
319                 string.Format("timestamp={0}",timestamp),
320                 string.Format("url={0}",url)
321             };
322             //字典排序
323             Array.Sort(arr);
324             //使用URL键值对的格式拼接成字符串
325             var temp = string.Join("&", arr);
326             return this._sign.Sha1(temp).ToLower();
327         }
328 
329         public JsApiTicket GetHsJsApiTicket(string accessToken)
330         {
331             JsApiTicket ticket = new JsApiTicket();
332             if (ticket.ticket == null)
333             {
334                 var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", accessToken);
335                 string ticketjson = SendGet(url);
336                 return JsonConvert.DeserializeObject<JsApiTicket>(ticketjson);
337             }
338             return ticket;
339         }
340 
341         public object JsApiSignature(string requestUrl) {
342             AccessToken accessToken = GetAccessToken();
343             JsApiTicket ticket = GetHsJsApiTicket(accessToken.access_token);
344             string nonceStr = CommonFiled.guid;
345             string timestamp = CommonFiled.unixTime10;
346             var WxConfig = new
347             {
348                 debug = false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
349                 appId = CommonFiled.appID, // 必填,公众号的唯一标识
350                 timestamp, // 必填,生成签名的时间戳
351                 nonceStr, // 必填,生成签名的随机串
352                 jsApiList = new string[] { "chooseImage", "previewImage", "getLocation" }, // 必填,需要使用的JS接口列表
353                 signature = GetJsApiSign(nonceStr, ticket.ticket, timestamp, requestUrl)
354             };
355             return WxConfig;
356         }
357 
358     }
359 }

 

posted @ 2020-08-28 09:07  一直傲娇的鲨鱼  阅读(58)  评论(0编辑  收藏  举报