目录
基本原理
公众号申请及配置
验证服务器有效性
接到请求后,需要做如下三步,若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。
将token、timestamp、nonce三个参数进行字典序排序
将三个参数字符串拼接成一个字符串进行sha1加密
开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.Security; using System.Xml; namespace WXHandler { /// <summary> /// wx 的摘要说明 /// </summary> public class wx : IHttpHandler { /// <summary> /// /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { WXContext wxContext = new WXContext(context); if (wxContext.IsHttpGet) //校验签名,在公众平台填入服务器端配置信息提交之后检验使用 { ValidateUrl(wxContext); } else { HandleMsg(wxContext); } } /// <summary> /// /// </summary> /// <param name="wxContext"></param> private void ValidateUrl(WXContext wxContext) { string echostr = string.Empty; bool success = BasicAPI.CheckSignature(wxContext, out echostr); if (success) { HttpContext context = HttpContext.Current; context.Response.ContentType = "text/plain"; context.Response.Write(echostr); } } /// <summary> /// /// </summary> /// <param name="wxContext"></param> public void HandleMsg(WXContext wxContext) { string msg = WeixinExecutor.Default.Execute(wxContext.WxMsg); HttpContext context = HttpContext.Current; context.Response.ContentType = "text/plain"; context.Response.Write(msg); } public bool IsReusable { get { return false; } } } }
检测代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using System.IO; namespace WXHandler { /// <summary> /// 对应微信API的 "基础支持" /// </summary> public class BasicAPI { /// <summary> /// 检查签名是否正确: /// </summary> /// <param name="wxContext"></param> /// <param name="echostr"></param> /// <returns></returns> public static bool CheckSignature(WXContext wxContext, out string echostr) { var arr = new[] {wxContext.Token,wxContext.Timetamp,wxContext.Nonce}.OrderBy(z => z).ToArray(); var arrString = string.Join("", arr); var sha1 = System.Security.Cryptography.SHA1.Create(); var sha1Arr = sha1.ComputeHash(Encoding.UTF8.GetBytes(arrString)); StringBuilder enText = new StringBuilder(); foreach (var b in sha1Arr) { enText.AppendFormat("{0:x2}", b); } echostr = enText.ToString(); return wxContext.Signature == enText.ToString(); } } }
微信请求消息类型
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Runtime.Serialization; using System.IO; namespace WXHandler { /// <summary> /// /// </summary> public class WeixinExecutor : IWeixinExecutor { /// <summary> /// /// </summary> public static WeixinExecutor Default { get { return new WeixinExecutor(); } } /// <summary> /// /// </summary> /// <param name="message"></param> /// <returns>已经打包成xml的用于回复用户的消息包</returns> public string Execute(WeixinMessage message) { string result = string.Empty; var openId = message.Body.FromUserName.Value; var myUserName = message.Body.ToUserName.Value; switch (message.Type) { case WeixinMessageType.Text://文字消息 { string userMessage = message.Body.Content.Value; var BotMessage = LuisService.Default.PostMessage(userMessage); result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage); } break; case WeixinMessageType.Image://图片消息 { string imageUrl = message.Body.PicUrl.Value;//图片地址 var msg = ImageService.Default.PostMessage(imageUrl); result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, msg); } break; case WeixinMessageType.Voice://语音消息 { var recognition = Convert.ToString(message.Body.Recognition.Value); var BotMessage = LuisService.Default.PostMessage(recognition); if (BotMessage == LuisInfos.DEFAULT_LUIS) BotMessage += string.Format(" 您输入的内容为:{0}", recognition); result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage); } break; case WeixinMessageType.Location://地理位置消息 { var location_X = message.Body.Location_X.Value.ToString(); var location_Y = message.Body.Location_Y.Value.ToString(); var BotMessage = LocationService.Default.PostMessage(location_Y, location_X); result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage); } break; case WeixinMessageType.Link://链接消息 { var title = message.Body.Title.Value.ToString(); var description = message.Body.Description.Value.ToString(); var url = message.Body.Url.Value.ToString(); var msgId = message.Body.MsgId.Value.ToString(); } break; default: result = ReplayPassiveMessageAPI.RepayText(openId, myUserName,"xxxxxx......"); break; } return result; } } }
原文:http://www.cnblogs.com/tgzhu/p/6219600.html