Exemplo n.º 1
0
        /// <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.QY.getEnum(msgType, Event);//ReceiveMessage_backup.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.Event_Location:
                rec = new ReceiveMessage.EventLocation();
                break;

            case ReceiveMessageEnum.Event_Click:
                rec = new ReceiveMessage.EventClick();
                break;

            case ReceiveMessageEnum.Event_View:
                break;

            case ReceiveMessageEnum.Event_Scancode_Push:
                break;

            case ReceiveMessageEnum.Event_Scancode_Waitmsg:
                break;

            case ReceiveMessageEnum.Event_Pic_Sysphoto:
                break;

            case ReceiveMessageEnum.Event_Pic_Photo_Or_Album:
                break;

            case ReceiveMessageEnum.Event_Pic_Weixin:
                break;

            case ReceiveMessageEnum.Event_Location_Select:
                break;

            case ReceiveMessageEnum.Event_Enter_Agent:
                rec = new ReceiveMessage.EventEnterAgent();
                break;

            case ReceiveMessageEnum.Event_Subscribe:
                rec = new ReceiveMessage.EventSubscribe();
                break;

            case ReceiveMessageEnum.Event_Batch_Job_Result:
                rec = new ReceiveMessage.EventBatchJobResult();
                break;

            default:
                break;
            }
            rec.FillReceiveMessageFromXml(xml);
            return(rec);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 开始处理
        /// </summary>
        public void Processing()
        {
            HttpContext context = HttpContext.Current;

            if (context == null || context.Request == null)
            {
                throw new Exception("HttpContext信息错误");
            }
            //this.MsgSig = HttpUtility.UrlDecode(context.Request.QueryString["msg_signature"], Encoding.UTF8);
            //this.TimeStamp = HttpUtility.UrlDecode(context.Request.QueryString["timestamp"], Encoding.UTF8);
            //this.Nonce = HttpUtility.UrlDecode(context.Request.QueryString["nonce"], Encoding.UTF8);
            //this.Echostr = HttpUtility.UrlDecode(context.Request.QueryString["echostr"], Encoding.UTF8);
            this.MsgSig    = context.Request.QueryString["msg_signature"];
            this.TimeStamp = context.Request.QueryString["timestamp"];
            this.Nonce     = context.Request.QueryString["nonce"];
            this.Echostr   = context.Request.QueryString["echostr"];

            if (AppSettings.IsDebug)
            {
                //DebugLog
                Logger.Info("MsgSig = " + MsgSig);
                Logger.Info("TimeStamp = " + TimeStamp);
                Logger.Info("Nonce = " + Nonce);
                Logger.Info("Echostr = " + Echostr);
            }

            if (string.IsNullOrEmpty(this.MsgSig) ||
                string.IsNullOrEmpty(this.TimeStamp) ||
                string.IsNullOrEmpty(this.Nonce))
            {
                throw new Exception("HttpContext信息错误");
            }
            int ret = 0;

            #region 微信平台开启回调模式,首次配置服务器信息时,校验服务器URL
            if (!string.IsNullOrEmpty(this.Echostr))
            {
                /*
                 * ------------使用示例一:验证回调URL---------------
                 *企业开启回调模式时,企业号会向验证url发送一个get请求
                 * 假设点击验证时,企业收到类似请求:
                 * GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
                 * HTTP/1.1 Host: qy.weixin.qq.com
                 *
                 * 接收到该请求时,企业应
                 * 1.解析出Get请求的参数,包括消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),
                 * 这一步注意作URL解码。
                 * 2.验证消息体签名的正确性
                 * 3.解密出echostr原文,将原文当作Get请求的response,返回给公众平台
                 * 第2,3步可以用公众平台提供的库函数VerifyURL来实现。
                 */

                string sEchoStr = "";
                ret = Wxcpt.VerifyURL(this.MsgSig, this.TimeStamp, this.Nonce, this.Echostr, ref sEchoStr);
                if (ret != 0)
                {
                    throw new Exception("ERR: VerifyURL Fail, errorCode: " + ret + "。");
                }
                //ret==0表示验证成功,sEchoStr参数表示明文,用户需要将sEchoStr作为get请求的返回参数,返回给企业号。

                context.Response.ContentType = "text/plain";
                context.Response.Write(sEchoStr);
                return;
            }
            #endregion

            //获取post请求内容
            StreamReader postData       = new StreamReader(context.Request.InputStream);
            string       postDataString = postData.ReadToEnd();

            if (AppSettings.IsDebug)
            {
                Logger.Info("postDataString = " + postDataString);
            }

            string sMsg = "";  // 解析之后的明文
            //解密
            ret = Wxcpt.DecryptMsg(MsgSig, TimeStamp, Nonce, postDataString, ref sMsg);
            if (ret != 0)
            {
                throw new Exception("ERR: Decrypt Fail, errorCode: " + ret);
            }

            if (AppSettings.IsDebug)
            {
                Logger.Info("sMsg = " + sMsg);
            }

            //解析XML
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(sMsg);

            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.Location:
                if (ProcessingLocation != null)
                {
                    ProcessingLocationEventArgs e = new ProcessingLocationEventArgs(messageEntity as ReceiveMessage.Location);
                    ProcessingLocation(this, e);
                    retMessage = e.ReplyMessage;
                }
                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_Scancode_Push:
                break;

            case ReceiveMessageEnum.Event_Scancode_Waitmsg:
                break;

            case ReceiveMessageEnum.Event_Pic_Sysphoto:
                break;

            case ReceiveMessageEnum.Event_Pic_Photo_Or_Album:
                break;

            case ReceiveMessageEnum.Event_Pic_Weixin:
                break;

            case ReceiveMessageEnum.Event_Location_Select:
                break;

            case ReceiveMessageEnum.Event_Enter_Agent:
                if (ProcessingEventEnterAgent != null)
                {
                    ProcessingEventEnterAgentEventArgs e = new ProcessingEventEnterAgentEventArgs(messageEntity as ReceiveMessage.EventEnterAgent);
                    ProcessingEventEnterAgent(this, e);
                    retMessage = e.ReplyMessage;
                }
                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_Batch_Job_Result:

                if (ProcessingEventBatchJobResult != null)
                {
                    ProcessingEventBatchJobResultEventArgs e = new ProcessingEventBatchJobResultEventArgs(messageEntity as ReceiveMessage.EventBatchJobResult);
                    ProcessingEventBatchJobResult(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 sEncryptMsg = ""; //xml格式的密文

            if (retMessage != null)
            {
                //未加密明文字符串
                string replyMsg = ReplyMessageBuilder.BuildXml(retMessage);

                if (AppSettings.IsDebug)
                {
                    Logger.Info("replyMsg = " + replyMsg);
                }

                //加密
                //string sEncryptMsg = ""; //xml格式的密文
                ret = Wxcpt.EncryptMsg(replyMsg, TimeStamp, Nonce, ref sEncryptMsg);
                if (ret != 0)
                {
                    throw new Exception("ERR: Encrypt Fail, errorCode: " + ret);
                }

                if (AppSettings.IsDebug)
                {
                    Logger.Info("sEncryptMsg = " + sEncryptMsg);
                }
            }

            context.Response.ContentType = "text/plain";
            context.Response.Write(sEncryptMsg);
        }