/// <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); }