/// <summary> /// 根据xml获取消息类型实体 /// </summary> /// <param name="xml">接收到消息解密后的xml</param> /// <param name="receiveMessageEnum">消息类型枚举</param> /// <returns>消息类型</returns> public static ReceiveMessage.Base Parse(XmlDocument xml, ref ReceiveMessageEnum receiveMessageEnum) { XmlNode root = xml.FirstChild; string msgType = root["MsgType"].InnerText.ToLower(); string Event = string.Empty; if (root["Event"] != null) { Event = root["Event"].InnerText.ToLower(); } receiveMessageEnum = Enums.MP.getEnum(msgType, Event); ReceiveMessage.Base rec = null; switch (receiveMessageEnum) { case ReceiveMessageEnum.Unknow: break; case ReceiveMessageEnum.Text: rec = new ReceiveMessage.Text(); break; case ReceiveMessageEnum.Image: rec = new ReceiveMessage.Image(); break; case ReceiveMessageEnum.Voice: rec = new ReceiveMessage.Voice(); break; case ReceiveMessageEnum.Video: rec = new ReceiveMessage.Video(); break; case ReceiveMessageEnum.ShortVideo: rec = new ReceiveMessage.ShortVideo(); break; case ReceiveMessageEnum.Location: rec = new ReceiveMessage.Location(); break; case ReceiveMessageEnum.Link: rec = new ReceiveMessage.Link(); break; case ReceiveMessageEnum.Event_Subscribe: rec = new ReceiveMessage.EventSubscribe(); break; case ReceiveMessageEnum.Event_Scan: rec = new ReceiveMessage.EventScan(); break; case ReceiveMessageEnum.Event_Location: rec = new ReceiveMessage.EventLocation(); break; case ReceiveMessageEnum.Event_Click: rec = new ReceiveMessage.EventClick(); break; case ReceiveMessageEnum.Event_View: rec = new ReceiveMessage.EventView(); break; case ReceiveMessageEnum.Event_MasssEndJobFinish: rec = new ReceiveMessage.EventMasssEndJobFinish(); break; default: break; } rec.FillReceiveMessageFromXml(xml); return(rec); }
/// <summary> /// 开始处理 /// </summary> public void Processing() { HttpContext context = HttpContext.Current; if (context == null || context.Request == null) { throw new Exception("HttpContext信息错误"); } this.Signature = context.Request.QueryString["signature"]; this.TimeStamp = context.Request.QueryString["timestamp"]; this.Nonce = context.Request.QueryString["nonce"]; this.Echostr = context.Request.QueryString["echostr"]; this.EncryptType = context.Request.QueryString["encrypt_type"]; this.MsgSignature = context.Request.QueryString["msg_signature"]; if (AppSettings.IsDebug) { //DebugLog Logger.Info("MsgSig = " + MsgSignature); Logger.Info("Signature = " + Signature); Logger.Info("TimeStamp = " + TimeStamp); Logger.Info("Nonce = " + Nonce); Logger.Info("Echostr = " + Echostr); Logger.Info("EncryptType = " + EncryptType); Logger.Info("MsgSignature = " + MsgSignature); } if (string.IsNullOrEmpty(this.Signature) || string.IsNullOrEmpty(this.TimeStamp) || string.IsNullOrEmpty(this.Nonce)) { throw new Exception("HttpContext信息错误"); } //校验Token签名(请求来源是否为微信服务器) if (!CheckSignature.Check(this.Signature, this.TimeStamp, this.Nonce, WechatConfig.Token)) { throw new Exception("ERR: VerifyURL Fail, 签名校验失败。"); } int ret = 0; #region 首次配置服务器信息时,直接返回Echostr if (!string.IsNullOrEmpty(this.Echostr)) { context.Response.ContentType = "text/plain"; context.Response.Write(Echostr); return; } #endregion //获取post请求内容 StreamReader postData = new StreamReader(context.Request.InputStream); string postDataString = postData.ReadToEnd(); if (AppSettings.IsDebug) { Logger.Info("postDataString = " + postDataString); } if (EncryptType == "aes") { //解密 ret = Wxcpt.DecryptMsg(MsgSignature, TimeStamp, Nonce, postDataString, ref postDataString); if (ret != 0) { throw new Exception("ERR: Decrypt Fail, errorCode: " + ret); } } if (AppSettings.IsDebug) { Logger.Info("sMsg = " + postDataString); } //解析XML XmlDocument doc = new XmlDocument(); doc.LoadXml(postDataString); ReceiveMessageEnum messageType = ReceiveMessageEnum.Unknow; ReceiveMessage.Base messageEntity = ReceiveMessageParser.Parse(doc, ref messageType); ReplyMessage.Base retMessage = null; #region 根据接收消息类型 执行相应事件 switch (messageType) { case ReceiveMessageEnum.Unknow: throw new Exception("未知的接收消息类型。"); case ReceiveMessageEnum.Text: if (ProcessingText != null) { ProcessingTextEventArgs e = new ProcessingTextEventArgs(messageEntity as ReceiveMessage.Text); ProcessingText(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Image: if (ProcessingImage != null) { ProcessingImageEventArgs e = new ProcessingImageEventArgs(messageEntity as ReceiveMessage.Image); ProcessingImage(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Voice: if (ProcessingVoice != null) { ProcessingVoiceEventArgs e = new ProcessingVoiceEventArgs(messageEntity as ReceiveMessage.Voice); ProcessingVoice(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Video: if (ProcessingVideo != null) { ProcessingVideoEventArgs e = new ProcessingVideoEventArgs(messageEntity as ReceiveMessage.Video); ProcessingVideo(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.ShortVideo: break; case ReceiveMessageEnum.Location: if (ProcessingLocation != null) { ProcessingLocationEventArgs e = new ProcessingLocationEventArgs(messageEntity as ReceiveMessage.Location); ProcessingLocation(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Link: break; case ReceiveMessageEnum.Event_Subscribe: if (ProcessingEventSubscribe != null) { ProcessingEventSubscribeEventArgs e = new ProcessingEventSubscribeEventArgs(messageEntity as ReceiveMessage.EventSubscribe); ProcessingEventSubscribe(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Event_Scan: break; case ReceiveMessageEnum.Event_Location: //如果开启位置记录,则缓存 if (this.EnablePositionRecord) { if (AppSettings.IsDebug) { Logger.Info("enablePositionRecord! key = " + CacheKey.UserLocation + messageEntity.FromUserName); } HttpContext.Current.Cache.Insert(CacheKey.UserLocation + messageEntity.FromUserName, messageEntity, null, DateTime.UtcNow.AddHours(this.PositionRecordExpiresHours), System.Web.Caching.Cache.NoSlidingExpiration); } if (ProcessingEventLocation != null) { ProcessingEventLocationEventArgs e = new ProcessingEventLocationEventArgs(messageEntity as ReceiveMessage.EventLocation); ProcessingEventLocation(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Event_Click: if (ProcessingEventClick != null) { ProcessingEventClickEventArgs e = new ProcessingEventClickEventArgs(messageEntity as ReceiveMessage.EventClick); ProcessingEventClick(this, e); retMessage = e.ReplyMessage; } break; case ReceiveMessageEnum.Event_View: break; case ReceiveMessageEnum.Event_MasssEndJobFinish: if (ProcessingEventMasssEndJobFinish != null) { ProcessingEventMasssEndJobFinishEventArgs e = new ProcessingEventMasssEndJobFinishEventArgs(messageEntity as ReceiveMessage.EventMasssEndJobFinish); ProcessingEventMasssEndJobFinish(this, e); retMessage = e.ReplyMessage; } break; default: throw new Exception("未知的接收消息类型。"); } #endregion if (AppSettings.IsDebug) { if (retMessage == null) { Logger.Info("retMessage = null"); } else { Logger.Log("retMessage = " + retMessage.ToString()); } } string replyMsg = ""; //xml格式字符串(明文或加密) if (retMessage != null) { //未加密明文字符串 replyMsg = ReplyMessageBuilder.BuildXml(retMessage); if (AppSettings.IsDebug) { Logger.Info("replyMsg = " + replyMsg); } if (EncryptType == "aes") { //加密 //replyMsg变为xml格式的密文 ret = Wxcpt.EncryptMsg(replyMsg, TimeStamp, Nonce, ref replyMsg); if (ret != 0) { throw new Exception("ERR: Encrypt Fail, errorCode: " + ret); } if (AppSettings.IsDebug) { Logger.Info("sEncryptMsg = " + replyMsg); } } } context.Response.ContentType = "text/plain"; context.Response.Write(replyMsg); }