Пример #1
0
        /// <summary>
        /// 发送微信信息,回复用户
        /// </summary>
        /// <param name="context"></param>
        /// <param name="toKen">微信账号toKen</param>
        /// <param name="GetData">回调函数,取回\回复给用户的消息内容</param>
        /// <param name="errorDescription"></param>
        public static bool Handle(HttpContext context, string toKen, DelegateGetData GetData, ref string errorDescription)
        {
            errorDescription = "";
            #region 验证请求的信息是否来自微信服务器

            bool sucessed = ValidSignature(context, toKen, ref errorDescription);

            if (!sucessed)
            {
                //context.Response.End(); //[shove]

                return(false);
            }

            #endregion

            #region 获取微信请求的内容

            Stream stream = null;//[shove] context.Request.InputStream;

            if (stream.Length < 1)
            {
                //errorDescription = "请求内容为空,无法解析。";
                //HttpContext.Current.Response.End();

                //return false;

                context.Response.WriteAsync(context.Request.Query["echoStr"]);
                //[shove] context.Response.End();

                return(true);
            }

            string requestContent = "";
            byte[] b = new byte[stream.Length];
            stream.Read(b, 0, (int)stream.Length);
            requestContent = Encoding.UTF8.GetString(b);

            if (string.IsNullOrEmpty(requestContent))
            {
                //errorDescription = "请求内容为空,无法解析。";
                //HttpContext.Current.Response.End();

                //return false;

                context.Response.WriteAsync(context.Request.Query["echoStr"]);
                //[shove] context.Response.End();

                return(true);
            }
            #endregion

            #region 分析微信请求的内容

            string FromUserName = "", ToUserName = "", Conten = "", MsgType = "";

            DateTime createTime;
            Message  requestMessage = new Message();

            XmlDocument doc = new XmlDocument();

            try
            {
                doc.LoadXml(requestContent);
                XmlNodeList list = doc.GetElementsByTagName("xml");
                XmlNode     xn   = list[0];

                FromUserName = xn.SelectSingleNode("//FromUserName").InnerText;
                ToUserName   = xn.SelectSingleNode("//ToUserName").InnerText;

                MsgType = xn.SelectSingleNode("//MsgType").InnerText;
                string Time = xn.SelectSingleNode("//CreateTime").InnerText;

                DateTime dtStart = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
                long     lTime   = long.Parse(xn.SelectSingleNode("//CreateTime").InnerText + "0000000");
                TimeSpan toNow   = new TimeSpan(lTime);
                createTime = dtStart.Add(toNow);

                // 判断用户点击了菜单栏还是自己发送的信息
                if (MsgType.ToLower().Equals("event")) //用户点击菜单
                {
                    string Event  = xn.SelectSingleNode("//Event").InnerText.ToLower();
                    string Ticket = "";//获取二维码Ticket;

                    //上报地理位置事件
                    if (Event.Equals("location"))
                    {
                        string _Latitude  = xn.SelectSingleNode("//Latitude").InnerText;
                        string _Longitude = xn.SelectSingleNode("//Longitude").InnerText;
                        string _Precision = xn.SelectSingleNode("//Precision").InnerText;

                        requestMessage = new RepuestGeographicalPositionmMessage
                                             (Event, _Latitude, _Longitude, _Precision, FromUserName, ToUserName, createTime, MsgType);
                    }
                    else if (Event.ToUpper().Equals("MASSSENDJOBFINISH"))//群发失败信息返回
                    {
                        string _MsgID       = xn.SelectSingleNode("//MsgID").InnerText;
                        string _Status      = xn.SelectSingleNode("//Status").InnerText;
                        string _TotalCount  = xn.SelectSingleNode("//TotalCount").InnerText;
                        string _FilterCount = xn.SelectSingleNode("//FilterCount ").InnerText;
                        long   _SentCount   = Shove.Convert.StrToLong(xn.SelectSingleNode("//SentCount").InnerText, -1);
                        long   _ErrorCount  = Shove.Convert.StrToLong(xn.SelectSingleNode("//ErrorCount").InnerText, -1);

                        requestMessage = new RequestSendFinishMessage(_MsgID, _Status, _TotalCount, _FilterCount, _SentCount, _ErrorCount);
                    }
                    else//事假推送
                    {
                        string EventKey = xn.SelectSingleNode("//EventKey").InnerText;

                        //是否是从二维码扫描关注
                        if (EventKey.IndexOf("qrscene") >= 0)
                        {
                            Ticket = EventKey.Split('_')[1];
                        }

                        requestMessage = new RequestEventMessage(Event, EventKey, Ticket, FromUserName, ToUserName, createTime, MsgType);
                    }
                }
                else if (MsgType.ToLower().Equals("image")) //微信用户发来的图片
                {
                    string Url     = xn.SelectSingleNode("//PicUrl").InnerText;
                    string MsgId   = xn.SelectSingleNode("//MsgId").InnerText;
                    string MediaId = xn.SelectSingleNode("//MediaId").InnerText;//图片ID

                    requestMessage = new RequestImageMessage(Url, MsgId, MediaId, FromUserName, ToUserName, createTime, MsgType);
                }
                else if (MsgType.ToLower().Equals("link")) // 微信用户发来的链接
                {
                    string title       = xn.SelectSingleNode("//Title").InnerText;
                    string Description = xn.SelectSingleNode("//Description").InnerText;
                    string Url         = xn.SelectSingleNode("//Url ").InnerText;
                    string MsgId       = xn.SelectSingleNode("//MsgId").InnerText;

                    requestMessage = new RequestLinkMessage(title, Description, Url, MsgId, FromUserName, ToUserName, createTime, MsgType);
                }
                else if (MsgType.ToLower().Equals("text"))               // 消息文本
                {
                    Conten = xn.SelectSingleNode("//Content").InnerText; //文本

                    requestMessage = new RequestTextMessage(Conten, FromUserName, ToUserName, createTime, MsgType);
                }
                else if (MsgType.ToLower().Equals("location"))                         // 地理位置
                {
                    string Location_X = xn.SelectSingleNode("//Location_X").InnerText; // 纬度
                    string Location_Y = xn.SelectSingleNode("//Location_Y").InnerText; // 经度
                    string Scale      = xn.SelectSingleNode("//Scale").InnerText;      // 地图缩放大小
                    string Label      = xn.SelectSingleNode("//Label").InnerText;      // 地理消息位置
                    string MsgId      = xn.SelectSingleNode("//MsgId").InnerText;

                    requestMessage = new RequestLocationMessage(Location_X, Location_Y, Scale, Label, MsgId, FromUserName, ToUserName, createTime, MsgType);
                }
                else if (MsgType.ToLower().Equals("video"))                                //视频类型
                {
                    string MediaId      = xn.SelectSingleNode("//MediaId").InnerText;      // 视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
                    string ThumbMediaId = xn.SelectSingleNode("//ThumbMediaId").InnerText; // 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
                    string MsgId        = xn.SelectSingleNode("//MsgId").InnerText;        //

                    requestMessage = new RequestVideoMessage(MediaId, ThumbMediaId, MsgId, FromUserName, ToUserName, createTime, MsgType);
                }
                else if (MsgType.ToLower().Equals("voice"))                                         //声音类型
                {
                    string MediaId     = xn.SelectSingleNode("//MediaId").InnerText;                // 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
                    string Format      = xn.SelectSingleNode("//Format").InnerText;                 // 语音格式,如amr,speex等
                    string MsgId       = xn.SelectSingleNode("//MsgId").InnerText;                  // 消息ID;
                    string Recognition = xn.SelectSingleNode("//Recognition").InnerText.ToString(); //语音识别结果,utf-8编码

                    requestMessage = new RequestVoiceMessage(MediaId, Format, MsgId, Recognition, FromUserName, ToUserName, createTime, MsgType);
                }
                else
                {
                    errorDescription = "请求内容无法解析类型。";
                    //[shove] context.Response.End();

                    return(false);
                }
            }
            catch (Exception e)
            {
                errorDescription = "请求内容格式错误,无法解析:" + e.Message;
                //[shove] context.Response.End();

                return(false);
            }

            #endregion

            #region 由应用程序返回消息内容

            List <Message> replyMessages = GetData(requestMessage, MsgType, ref errorDescription);

            if ((replyMessages == null) || (replyMessages.Count < 1))
            {
                //[shove] context.Response.End();

                return(true);
            }

            #endregion

            #region 构建回复消息,并返回给微信服务器

            StringBuilder reply = new StringBuilder();

            reply.Append("<xml>");
            reply.Append("<ToUserName><![CDATA[" + FromUserName + "]]></ToUserName>");
            reply.Append("<FromUserName><![CDATA[" + ToUserName + "]]></FromUserName>");
            reply.Append("<CreateTime><![CDATA[" + DateTime.Now.Ticks.ToString() + "]]></CreateTime>");
            reply.Append("<MsgType><![CDATA[" + replyMessages[0].MsgType + "]]></MsgType>");

            for (int i = 0; i < replyMessages.Count; i++)
            {
                if (replyMessages[i] is TextMessage)
                {
                    TextMessage message = replyMessages[i] as TextMessage;
                    int         len     = Shove.String.GetLength(message.Content);

                    if (len > 2048)
                    {
                        errorDescription = "文本内容字节长度不能超过 2048。";
                        //[shove] context.Response.End();

                        return(false);
                    }

                    reply.Append("<Content><![CDATA[" + message.Content + "]]></Content>");
                }
                else if (replyMessages[i] is ImageTextMessage)
                {
                    ImageTextMessage message = replyMessages[i] as ImageTextMessage;
                    string           Ext     = System.IO.Path.GetExtension(message.PicUrl).ToLower();

                    if (!Ext.Equals(".png") && !Ext.Equals(".jpg"))
                    {
                        errorDescription = "图片格式不正确,只能是:jpg、png。";
                        //[shove] context.Response.End();

                        return(false);
                    }

                    if (System.Convert.ToInt32(message.ArticleCount) > 10 || replyMessages.Count > 10)
                    {
                        errorDescription = "图文信息超出 10 条限制。";
                        //[shove] context.Response.End();

                        return(false);
                    }

                    if (i == 0)
                    {
                        reply.Append("<ArticleCount>" + message.ArticleCount + "</ArticleCount>");
                        reply.Append("<Articles>");
                    }

                    reply.Append("<item>");
                    reply.Append("<Title><![CDATA[" + message.Title + "]]></Title>");
                    reply.Append("<Description><![CDATA[" + message.Description + "]]></Description>");
                    reply.Append("<PicUrl><![CDATA[" + message.PicUrl + "]]></PicUrl>");
                    reply.Append("<Url><![CDATA[" + message.Url + "]]></Url>");
                    reply.Append("</item>");

                    if (i == replyMessages.Count - 1)
                    {
                        reply.Append("</Articles>");
                    }
                }
                else if (replyMessages[i] is MusicMessage)
                {
                    MusicMessage message = replyMessages[i] as MusicMessage;

                    reply.Append("<Music>");
                    reply.Append("<Title><![CDATA[" + message.Title + "]]></Title>");
                    reply.Append("<Description><![CDATA[" + message.Description + "]]></Description>");
                    reply.Append("<MusicUrl><![CDATA[" + message.MusicUrl + "]]></MusicUrl>");
                    reply.Append("<HQMusicUrl><![CDATA[" + message.HQMusicUrl + "]]></HQMusicUrl>");
                    reply.Append("</Music>");
                }
                else if (replyMessages[i] is VoiceMessage)
                {
                    VoiceMessage Voice = replyMessages[i] as VoiceMessage;

                    if (string.IsNullOrEmpty(Voice.MediaId))
                    {
                        errorDescription = "音频媒体ID为空,";
                        //[shove] context.Response.End();

                        return(false);
                    }

                    reply.Append("<Voice>");
                    reply.Append("<MediaId><![CDATA[" + Voice.MediaId + "]]></MediaId>");
                    reply.Append("</Voice>");
                }
                else if (replyMessages[i] is VideoMessage)
                {
                    VideoMessage Video = replyMessages[i] as VideoMessage;

                    if (string.IsNullOrEmpty(Video.MediaId))
                    {
                        errorDescription = "视频媒体ID为空,";
                        //[shove] context.Response.End();

                        return(false);
                    }

                    reply.Append("<Video>");
                    reply.Append("<MediaId><![CDATA[" + Video.MediaId + "]]></MediaId>");
                    reply.Append("<Title><![CDATA[" + Video.Title + "]]></Title>");
                    reply.Append("<Description><![CDATA[" + Video.Description + "]]></Description>");
                    reply.Append("</Video>");
                }
                else if (replyMessages[i] is CustomerServiceMessage)
                {
                }
                else
                {
                    errorDescription = "暂不支持回复此类型的消息。";
                    //[shove] context.Response.End();

                    return(false);
                }
            }

            reply.Append("</xml>");

            context.Response.WriteAsync(reply.ToString());

            #endregion

            return(true);
        }