Asp.net MVC实现微信扫码后推送消息

mac2025-06-06  73

首先说下需求:

我有一个网站,网站上有很多作者分享自己的作品,如果其他用户浏览作品后想联系这位作者,就需要扫码关注我们的平台,我们会推送对方的联系方式。

第一步,生成带参数的二维码

步骤:

1.用微信appid和appsecret获取access_token

2.用access_token获取二维码的ticket,这其中要用json格式传入固定格式的值才能获取到ticket,传值的时候你可以在scene_id中带上自己的参数,方便用户扫码后回调的时候处理

3.用ticket直接得到二维码图片(注意:用这个方式,微信服务器返回的是图片的数据流。如果你需要处理二维码的图片,你不需要考虑如何操作这个数据流,只需要把整个访问微信的字符串带上ticket当成一个图片的地址放在src中就可以了,你可以操作图片本身)

下面是代码,省略了一些处理返回值的model类

/// <summary> /// 生成二维码 /// </summary> /// <returns></returns> [HttpPost] public IHttpActionResult CreateImg(dynamic data) { //用户ID int uid = Convert.ToInt32(data.userid); //get token string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=**********&secret=****************"); var wm = new System.Net.Http.HttpClient().GetAsync(url).Result.Content.ReadAsStringAsync().Result; WechatModels info = JsonConvert.DeserializeObject<WechatModels>(wm); //get ticket string turl = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", info.access_token); var jsonInfo = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + uid + "}}}"; HttpContent httpContent = new StringContent(jsonInfo); httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var tickets = new System.Net.Http.HttpClient().PostAsync(turl, httpContent).Result.Content.ReadAsStringAsync().Result; TicketInfo tinfo = JsonConvert.DeserializeObject<TicketInfo>(tickets); //get imgUrl string imgUrl = string.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", System.Web.HttpUtility.UrlEncode(tinfo.ticket)); //var res = new System.Net.Http.HttpClient().GetAsync(imgUrl).Result.Content.ReadAsStringAsync().Result; return Json(imgUrl); }

第二步,用户扫码后的处理

处理的前提是你已经在公众号中配置完成

如图,服务器地址中的方法,就是扫码后的回调地址,也是之前一开始你配置服务器时处理token的回调地址

 

 

 下面插入回调处理的代码

 

/// <summary> /// 接收微信推送 /// </summary> public void Valid() { Stream requestStream = System.Web.HttpContext.Current.Request.InputStream; string result = ""; string postString = string.Empty; //处理扫码后的回调,参考微信公众平台开发文档中给出的回调数据 if (System.Web.HttpContext.Current.Request.HttpMethod.ToUpper() == "POST") { using (Stream stream = System.Web.HttpContext.Current.Request.InputStream) { Byte[] postBytes = new Byte[stream.Length]; stream.Read(postBytes, 0, (Int32)stream.Length); postString = Encoding.UTF8.GetString(postBytes); if (!string.IsNullOrEmpty(postString)) { string SendToWx = string.Empty; //这里写方法解析Xml XmlDocument xml = new XmlDocument();// xml.LoadXml(postString); XmlElement xmlElement = xml.DocumentElement; //这里进行判断MsgType switch (xmlElement.SelectSingleNode("MsgType").InnerText) { case "voice": break; case "video": break; case "shortvideo": break; case "location": break; case "link": break; case "event": //扫码后的MsgType是event,在这里解析微信服务器的推送数据,我们再按照要求的格式推送给用户 string FromUserName = xmlElement.SelectSingleNode("FromUserName").InnerText == null ? "" : xmlElement.SelectSingleNode("FromUserName").InnerText; string ToUserName = xmlElement.SelectSingleNode("ToUserName").InnerText == null ? "" : xmlElement.SelectSingleNode("ToUserName").InnerText; string CreateTime = xmlElement.SelectSingleNode("CreateTime").InnerText == null ? "" : xmlElement.SelectSingleNode("CreateTime").InnerText; string eventKey = xmlElement.SelectSingleNode("EventKey").InnerText == null ? "" : xmlElement.SelectSingleNode("EventKey").InnerText; //这里需要注意,扫码后的eventKey就是你之前的场景值,但是如果用户没有关注,用户先选择了关注,那这里的eventKey就会多一个“qrscene_”的前缀,这在文档中有说明,但容易忽略,所以这里做一下处理 if (eventKey.Contains("_")) { eventKey = eventKey.Split('_')[1]; } //我在这里通过场景值来查询用户信息,再把用户需要的信息发送出去 var user = Helper.Comm.HttpPost2(ip + "/api/Index/QueryWorks", new Dictionary<string, string>() { { "uid", eventKey } }); TalentPool contents = JsonConvert.DeserializeObject<TalentPool>(user); //把联系方式发送给对方 string tips = "感谢关注!" + contents.Name + "的微信号是:" + contents.WX + " "; //拼接xml或json格式的数据,才能正确发送给用户 string jsoninfo = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + CreateTime + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + tips + "]]></Content></xml>"; //把数据转化为json格式 HttpContent httpContent = new StringContent(jsoninfo); httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); switch (xmlElement.SelectSingleNode("Event").InnerText) { case "subscribe": System.Web.HttpContext.Current.Response.Write(jsoninfo);//关注事件 通过C#自带的Response.Write方法,就能把需要的信息发给扫码的人 System.Web.HttpContext.Current.Response.End(); break; case "unsubscribe": System.Web.HttpContext.Current.Response.Write(jsoninfo); System.Web.HttpContext.Current.Response.End(); break; case "SCAN": System.Web.HttpContext.Current.Response.Write(jsoninfo);//扫码事件 System.Web.HttpContext.Current.Response.End(); break; case "LOCATION": break; case "CLICK": break; case "VIEW": break; default: break; } break; default: result = "没有识别的类型消息:" + xmlElement.SelectSingleNode("MsgType").InnerText; WriteLog(result); break; } if (!string.IsNullOrEmpty(SendToWx)) { System.Web.HttpContext.Current.Response.Write(SendToWx); System.Web.HttpContext.Current.Response.End(); } else { result = "回传数据为空"; WriteLog(result); } } else { result = "微信推送的数据为:" + postString; WriteLog(result); } } } else if (Request.HttpMethod.ToUpper() == "GET") { //这里是之前你配置微信服务的时候验证token令牌的方法处理,可以删掉但没必要 string token = ConfigurationManager.AppSettings["WXToken"];//从配置文件获取Token if (string.IsNullOrEmpty(token)) { result = string.Format("微信Token配置项没有配置!"); WriteLog(result); } string echoString = System.Web.HttpContext.Current.Request.QueryString["echoStr"]; string signature = System.Web.HttpContext.Current.Request.QueryString["signature"]; string timestamp = System.Web.HttpContext.Current.Request.QueryString["timestamp"]; string nonce = System.Web.HttpContext.Current.Request.QueryString["nonce"]; if (CheckSignature(token, signature, timestamp, nonce)) { if (!string.IsNullOrEmpty(echoString)) { System.Web.HttpContext.Current.Response.Write(echoString); System.Web.HttpContext.Current.Response.End(); result = string.Format("微信Token配置成功,你已成为开发者!"); WriteLog(result); } } } } //token验证 public bool CheckSignature(string token, string signature, string timestamp, string nonce) { string[] ArrTmp = { token, timestamp, nonce }; Array.Sort(ArrTmp); string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); tmpStr = tmpStr.ToLower(); if (tmpStr == signature) { return true; } else { return false; } } //写入日志 private void WriteLog(string str) { try { using (System.IO.FileStream fs = new System.IO.FileStream(Server.MapPath("Upload/log.txt"), System.IO.FileMode.Append)) { using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fs)) { string strlog = "----" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + str + "-----"; sw.WriteLine(strlog); sw.Close(); } } } catch { } }

至此你就完成了用户扫码后获得自定义消息的流程,代码中省略了一些前端的处理,以及一些实体类的代码,但不影响阅读

微信公众平台中,提供了日志查看的功能,微信开发调试起来并不那么方便,可以通过日志来查看

 

 总体来讲,微信开发文档基本很简洁,没有什么案例,网上的资料很多也是无效的资料,对于新手来讲,微信开发确实是比较头痛,在此记录一下,希望这篇案例对大家有帮助。

最新回复(0)