public void RequestXmlTest() { var url = "https://sdk.weixin.senparc.com/weixin"; //可以换成你自己的地址 var token = "weixin"; //替换成自己的Token var requestXml = @"<?xml version=""1.0"" encoding=""utf-8""?> <xml> <ToUserName><![CDATA[gh_a96a4a619366]]></ToUserName> <FromUserName><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></FromUserName> <CreateTime>1384322309</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[CLICK]]></Event> <EventKey><![CDATA[OneClick]]></EventKey> </xml>"; var xml = MessageAgent.RequestXml(null, url, token, requestXml); var responseMessage = ResponseMessageBase.CreateFromResponseXml(xml, MpMessageEntityEnlightener.Instance); Assert.IsNotNull(responseMessage); Assert.IsInstanceOfType(responseMessage, typeof(ResponseMessageText)); var strongResponseMessage = responseMessage as ResponseMessageText; Assert.IsTrue(strongResponseMessage.Content.Contains("您点击了底部按钮。")); Console.Write(strongResponseMessage.Content); }
/// <summary> /// 模拟并发请求 /// </summary> /// <param name="url"></param> /// <param name="token"></param> /// <param name="requestMessaageDoc"></param> /// <returns></returns> private string TestAsyncTask(string url, string token, XDocument requestMessaageDoc) { //修改MsgId,防止被去重 if (requestMessaageDoc.Root.Element("MsgId") != null) { requestMessaageDoc.Root.Element("MsgId").Value = Senparc.Weixin.Helpers.DateTimeHelper.GetWeixinDateTime(DateTime.Now.AddSeconds(Thread.CurrentThread.GetHashCode())).ToString(); } var responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString(), 1000 * 20); Thread.Sleep(100); //模拟服务器响应时间 return responseMessageXml; }
public ActionResult Index(string url, string token, RequestMsgType requestType, Event?eventType) { using (MemoryStream ms = new MemoryStream()) { var requestMessaageDoc = GetrequestMessaageDoc(url, token, requestType, eventType); requestMessaageDoc.Save(ms); ms.Seek(0, SeekOrigin.Begin); var responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString()); return(Content(responseMessageXml)); } }
/// <summary> /// 模拟并发请求 /// </summary> /// <param name="url"></param> /// <param name="token"></param> /// <param name="requestMessaageDoc"></param> /// <returns></returns> private string TestAsyncTask(string url, string token, XDocument requestMessaageDoc) { //修改MsgId,防止被去重 if (requestMessaageDoc.Root.Element("MsgId") != null) { requestMessaageDoc.Root.Element("MsgId").Value = DateTimeHelper.GetUnixDateTime(SystemTime.Now.AddSeconds(Thread.CurrentThread.GetHashCode())).ToString(); } var responseMessageXml = MessageAgent.RequestXml(null, url, token, xml: requestMessaageDoc.ToString(), autoFillUrlParameters: true, timeOut: 1000 * 20); Thread.Sleep(100); //模拟服务器响应时间 return(responseMessageXml); }
/// <summary> /// 模拟并发请求 /// </summary> /// <param name="url"></param> /// <param name="token"></param> /// <param name="requestMessaageDoc"></param> /// <param name="autoFillUrlParameters">是否自动填充Url中缺少的参数(signature、timestamp、nonce),默认为 true</param> /// <returns></returns> private string TestAsyncTask(string url, string token, XDocument requestMessaageDoc, bool autoFillUrlParameters, int sleepMillionSeconds = 0) { //修改MsgId,防止被去重 if (requestMessaageDoc.Root.Element("MsgId") != null) { requestMessaageDoc.Root.Element("MsgId").Value = DateTimeHelper.GetUnixDateTime(SystemTime.Now.AddSeconds(token.GetHashCode())).ToString(); } var responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString(), autoFillUrlParameters, 1000 * 20); Thread.Sleep(sleepMillionSeconds); //模拟服务器响应时间 return(responseMessageXml); }
public ActionResult Index(string url, string token, RequestMsgType requestType, Event?eventType, bool testConcurrence, int testConcurrenceCount) { using (MemoryStream ms = new MemoryStream()) { var requestMessaageDoc = GetrequestMessaageDoc(url, token, requestType, eventType); requestMessaageDoc.Save(ms); ms.Seek(0, SeekOrigin.Begin); var responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString()); if (string.IsNullOrEmpty(responseMessageXml)) { responseMessageXml = "返回消息为空,可能已经被去重。\r\nMsgId相同的连续消息将被自动去重。"; } try { DateTime dt1 = DateTime.Now; if (testConcurrence) { testConcurrenceCount = testConcurrenceCount > 30 ? 30 : testConcurrenceCount;//设定最高限额 //模拟并发请求 List <Task <string> > taskList = new List <Task <string> >(); for (int i = 0; i < testConcurrenceCount; i++) { var task = Task.Factory.StartNew(() => TestAsyncTask(url, token, requestMessaageDoc)); taskList.Add(task); } Task.WaitAll(taskList.ToArray(), 1000 * 10); } DateTime dt2 = DateTime.Now; var data = new { Success = true, LoadTime = (dt2 - dt1).TotalMilliseconds.ToString("##.####"), Result = responseMessageXml }; return(Json(data, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })); } catch (Exception ex) { var msg = string.Format("{0}\r\n{1}\r\n{2}", ex.Message, null, ex.InnerException != null ? ex.InnerException.Message : null); return(Json(new { Success = false, Result = msg }, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })); } } }
public ActionResult Index(string url, string token, RequestMsgType requestType, Event?eventType) { using (MemoryStream ms = new MemoryStream()) { var requestMessaageDoc = GetrequestMessaageDoc(url, token, requestType, eventType); requestMessaageDoc.Save(ms); ms.Seek(0, SeekOrigin.Begin); var responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString()); if (string.IsNullOrEmpty(responseMessageXml)) { responseMessageXml = "返回消息为空,可能已经被去重。\r\nMsgId相同的连续消息将被自动去重。"; } return(Content(responseMessageXml)); } }
/// <summary> /// 处理文字请求 /// </summary> /// <param name="requestMessage">请求消息</param> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //说明:实际项目中这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs #region 书中例子 //if (requestMessage.Content == "你好") //{ // var responseMessage = base.CreateResponseMessage<ResponseMessageNews>(); // var title = "Title"; // var description = "Description"; // var picUrl = "PicUrl"; // var url = "Url"; // responseMessage.Articles.Add(new Article() // { // Title = title, // Description = description, // PicUrl = picUrl, // Url = url // }); // return responseMessage; //} //else if (requestMessage.Content == "Senparc") //{ // //相似处理逻辑 //} //else //{ // //... //} #endregion #region 历史方法 //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using Senparc.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 #endregion var defaultResponseMessage = base.CreateResponseMessage <ResponseMessageText>(); var requestHandler = requestMessage.StartHandler() //关键字不区分大小写,按照顺序匹配成功后将不再运行下面的逻辑 .Keyword("约束", () => { defaultResponseMessage.Content = @"您正在进行微信内置浏览器约束判断测试。您可以: <a href=""https://sdk.weixin.senparc.com/FilterTest/"">点击这里</a>进行客户端约束测试(地址:https://sdk.weixin.senparc.com/FilterTest/),如果在微信外打开将直接返回文字。 或: <a href=""https://sdk.weixin.senparc.com/FilterTest/Redirect"">点击这里</a>进行客户端约束测试(地址:https://sdk.weixin.senparc.com/FilterTest/Redirect),如果在微信外打开将重定向一次URL。"; return(defaultResponseMessage); }). //匹配任一关键字 Keywords(new[] { "托管", "代理" }, () => { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 var dt1 = SystemTime.Now; //计时开始 var agentXml = RequestDocument.ToString(); #region 暂时转发到SDK线上Demo agentUrl = "https://sdk.weixin.senparc.com/weixin"; //agentToken = WebConfigurationManager.AppSettings["WeixinToken"];//Token //修改内容,防止死循环 var agentDoc = XDocument.Parse(agentXml); agentDoc.Root.Element("Content").SetValue("代理转发文字:" + requestMessage.Content); agentDoc.Root.Element("CreateTime").SetValue(DateTimeHelper.GetUnixDateTime(SystemTime.Now)); //修改时间,防止去重 agentDoc.Root.Element("MsgId").SetValue("123"); //防止去重 agentXml = agentDoc.ToString(); #endregion var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, agentXml); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有WeiweihiKey,可以直接使用下面的这个MessageAgent.RequestWeiweihiXml()方法。 * WeiweihiKey专门用于对接www.weiweihi.com平台,获取方式见:https://www.weiweihi.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestWeiweihiXml(weiweihiKey, RequestDocument.ToString());//获取Weiweihi返回的XML var dt2 = SystemTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ var msg = string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); var agentResponseMessage = responseXml.CreateResponseMessage(this.MessageEntityEnlightener); if (agentResponseMessage is ResponseMessageText) { (agentResponseMessage as ResponseMessageText).Content += msg; } else if (agentResponseMessage is ResponseMessageNews) { (agentResponseMessage as ResponseMessageNews).Articles[0].Description += msg; } return(agentResponseMessage); //可能出现多种类型,直接在这里返回 }) .Keywords(new[] { "测试", "退出" }, () => { /* * 这是一个特殊的过程,此请求通常来自于微微嗨(http://www.weiweihi.com)的“盛派网络小助手”应用请求(https://www.weiweihi.com/User/App/Detail/1), * 用于演示微微嗨应用商店的处理过程,由于微微嗨的应用内部可以单独设置对话过期时间,所以这里通常不需要考虑对话状态,只要做最简单的响应。 */ if (defaultResponseMessage.Content == "测试") { //进入APP测试 defaultResponseMessage.Content = "您已经进入【盛派网络小助手】的测试程序,请发送任意信息进行测试。发送文字【退出】退出测试对话。10分钟内无任何交互将自动退出应用对话状态。"; } else { //退出APP测试 defaultResponseMessage.Content = "您已经退出【盛派网络小助手】的测试程序。"; } return(defaultResponseMessage); }) .Keyword("AsyncTest", () => { //异步并发测试(提供给单元测试使用) #if NET45 var begin = SystemTime.Now; int t1, t2, t3; System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3); System.Threading.ThreadPool.GetMaxThreads(out t2, out t3); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4)); var end = SystemTime.Now; var thread = System.Threading.Thread.CurrentThread; defaultResponseMessage.Content = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, HttpContext.Current != null ? HttpContext.Current.ApplicationInstance.GetHashCode() : -1, begin, end, t2 - t1 ); #endif return(defaultResponseMessage); }) .Keyword("OPEN", () => { var openResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageNews>(); openResponseMessage.Articles.Add(new Article() { Title = "开放平台微信授权测试!", Description = @"点击进入Open授权页面。 授权之后,您的微信所收到的消息将转发到第三方(盛派网络小助手)的服务器上,并获得对应的回复。 测试完成后,您可以登陆公众号后台取消授权。", Url = "https://sdk.weixin.senparc.com/OpenOAuth/JumpToMpOAuth" }); return(openResponseMessage); }) .Keyword("错误", () => { var errorResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); //因为没有设置errorResponseMessage.Content,所以这小消息将无法正确返回。 return(errorResponseMessage); }) .Keyword("容错", () => { Thread.Sleep(4900); //故意延时1.5秒,让微信多次发送消息过来,观察返回结果 var faultTolerantResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); faultTolerantResponseMessage.Content = string.Format("测试容错,MsgId:{0},Ticks:{1}", requestMessage.MsgId, SystemTime.Now.Ticks); return(faultTolerantResponseMessage); }) .Keyword("TM", () => { var openId = requestMessage.FromUserName; var checkCode = Guid.NewGuid().ToString("n").Substring(0, 3); //为了防止openId泄露造成骚扰,这里启用验证码 TemplateMessageCollection[checkCode] = openId; defaultResponseMessage.Content = string.Format(@"新的验证码为:{0},请在网页上输入。网址:https://sdk.weixin.senparc.com/AsyncMethods", checkCode); return(defaultResponseMessage); }) .Keyword("OPENID", () => { var openId = requestMessage.FromUserName; //获取OpenId var userInfo = UserApi.Info(appId, openId, Language.zh_CN); defaultResponseMessage.Content = string.Format( "您的OpenID为:{0}\r\n昵称:{1}\r\n性别:{2}\r\n地区(国家/省/市):{3}/{4}/{5}\r\n关注时间:{6}\r\n关注状态:{7}", requestMessage.FromUserName, userInfo.nickname, (WeixinSex)userInfo.sex, userInfo.country, userInfo.province, userInfo.city, DateTimeHelper.GetDateTimeFromXml(userInfo.subscribe_time), userInfo.subscribe); return(defaultResponseMessage); }) .Keyword("EX", () => { var ex = new WeixinException("openid:" + requestMessage.FromUserName + ":这是一条测试异常信息"); //回调过程在global的ConfigWeixinTraceLog()方法中 defaultResponseMessage.Content = "请等待异步模板消息发送到此界面上(自动延时数秒)。\r\n当前时间:" + SystemTime.Now.ToString(); return(defaultResponseMessage); }) .Keyword("MUTE", () => //不回复任何消息 { //方案一: return(new SuccessResponseMessage()); //方案二: var muteResponseMessage = base.CreateResponseMessage <ResponseMessageNoResponse>(); return(muteResponseMessage); //方案三: base.TextResponseMessage = "success"; return(null); //方案四: return(null); //在 Action 中结合使用 return new FixWeixinBugWeixinResult(messageHandler); }) .Keyword("JSSDK", () => { defaultResponseMessage.Content = "点击打开:https://sdk.weixin.senparc.com/WeixinJsSdk"; return(defaultResponseMessage); }) //选择菜单,关键字:101(微信服务器端最终格式:id="s:101",content="满意") .SelectMenuKeyword("101", () => { defaultResponseMessage.Content = $"感谢您的评价({requestMessage.Content})!我们会一如既往为提高企业和开发者生产力而努力!"; return(defaultResponseMessage); }) //选择菜单,关键字:102(微信服务器端最终格式:id="s:102",content="一般") .SelectMenuKeyword("102", () => { defaultResponseMessage.Content = $"感谢您的评价({requestMessage.Content})!希望我们的服务能让您越来越满意!"; return(defaultResponseMessage); }) //选择菜单,关键字:103(微信服务器端最终格式:id="s:103",content="不满意") .SelectMenuKeyword("103", () => { defaultResponseMessage.Content = $"感谢您的评价({requestMessage.Content})!我们需要您的意见或建议,欢迎向我们反馈! <a href=\"https://github.com/JeffreySu/WeiXinMPSDK/issues/new\">点击这里</a>"; return(defaultResponseMessage); }) .SelectMenuKeywords(new[] { "110", "111" }, () => { defaultResponseMessage.Content = $"这里只是演示,可以同时支持多个选择菜单"; return(defaultResponseMessage); }) //Default不一定要在最后一个 .Default(() => { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToString("HH:mm:ss"), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", GlobalMessageContext.ExpireMinutes, GlobalMessageContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com"); defaultResponseMessage.Content = result.ToString(); return(defaultResponseMessage); }) //“一次订阅消息”接口测试 .Keyword("订阅", () => { defaultResponseMessage.Content = "点击打开:https://sdk.weixin.senparc.com/SubscribeMsg"; return(defaultResponseMessage); }) //正则表达式 .Regex(@"^\d+#\d+$", () => { defaultResponseMessage.Content = string.Format("您输入了:{0},符合正则表达式:^\\d+#\\d+$", requestMessage.Content); return(defaultResponseMessage); }); return(requestHandler.GetResponseMessage() as IResponseMessageBase); }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs //书中例子 //if (requestMessage.Content == "你好") //{ // var responseMessage = base.CreateResponseMessage<ResponseMessageNews>(); // var title = "Title"; // var description = "Description"; // var picUrl = "PicUrl"; // var url = "Url"; // responseMessage.Articles.Add(new Article() // { // Title = title, // Description = description, // PicUrl = picUrl, // Url = url // }); // return responseMessage; //} //else if (requestMessage.Content == "Senparc") //{ // //相似处理逻辑 //} //else //{ // //... //} //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using Senparc.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 var responseMessage = base.CreateResponseMessage <ResponseMessageText>(); if (requestMessage.Content == null) { } else if (requestMessage.Content == "约束") { responseMessage.Content = @"您正在进行微信内置浏览器约束判断测试。您可以: <a href=""http://sdk.weixin.senparc.com/FilterTest/"">点击这里</a>进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/),如果在微信外打开将直接返回文字。 或: <a href=""http://sdk.weixin.senparc.com/FilterTest/Redirect"">点击这里</a>进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/Redirect),如果在微信外打开将重定向一次URL。"; } else if (requestMessage.Content == "托管" || requestMessage.Content == "代理") { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, RequestDocument.ToString()); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有WeiweihiKey,可以直接使用下面的这个MessageAgent.RequestWeiweihiXml()方法。 * WeiweihiKey专门用于对接www.weiweihi.com平台,获取方式见:http://www.weiweihi.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestWeiweihiXml(weiweihiKey, RequestDocument.ToString());//获取Weiweihi返回的XML DateTime dt2 = DateTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ var msg = string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); var agentResponseMessage = responseXml.CreateResponseMessage(); if (agentResponseMessage is ResponseMessageText) { (agentResponseMessage as ResponseMessageText).Content += msg; } else if (agentResponseMessage is ResponseMessageNews) { (agentResponseMessage as ResponseMessageNews).Articles[0].Description += msg; } return(agentResponseMessage);//可能出现多种类型,直接在这里返回 } else if (requestMessage.Content == "测试" || requestMessage.Content == "退出") { /* * 这是一个特殊的过程,此请求通常来自于微微嗨(http://www.weiweihi.com)的“盛派网络小助手”应用请求(http://www.weiweihi.com/User/App/Detail/1), * 用于演示微微嗨应用商店的处理过程,由于微微嗨的应用内部可以单独设置对话过期时间,所以这里通常不需要考虑对话状态,只要做最简单的响应。 */ if (requestMessage.Content == "测试") { //进入APP测试 responseMessage.Content = "您已经进入【盛派网络小助手】的测试程序,请发送任意信息进行测试。发送文字【退出】退出测试对话。10分钟内无任何交互将自动退出应用对话状态。"; } else { //退出APP测试 responseMessage.Content = "您已经退出【盛派网络小助手】的测试程序。"; } } else if (requestMessage.Content == "AsyncTest") { //异步并发测试(提供给单元测试使用) DateTime begin = DateTime.Now; int t1, t2, t3; System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3); System.Threading.ThreadPool.GetMaxThreads(out t2, out t3); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4)); DateTime end = DateTime.Now; var thread = System.Threading.Thread.CurrentThread; responseMessage.Content = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, HttpContext.Current != null ? HttpContext.Current.ApplicationInstance.GetHashCode() : -1, begin, end, t2 - t1 ); } else if (requestMessage.Content == "open") { var openResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageNews>(); openResponseMessage.Articles.Add(new Article() { Title = "开放平台微信授权测试", Description = @"点击进入Open授权页面。 授权之后,您的微信所收到的消息将转发到第三方(盛派网络小助手)的服务器上,并获得对应的回复。 测试完成后,您可以登陆公众号后台取消授权。", Url = "http://sdk.weixin.senparc.com/OpenOAuth/JumpToMpOAuth" }); return(openResponseMessage); } else if (requestMessage.Content == "错误") { var errorResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); //因为没有设置errorResponseMessage.Content,所以这小消息将无法正确返回。 return(errorResponseMessage); } else if (requestMessage.Content == "容错") { Thread.Sleep(1500);//故意延时1.5秒,让微信多次发送消息过来,观察返回结果 var faultTolerantResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); faultTolerantResponseMessage.Content = string.Format("测试容错,MsgId:{0},Ticks:{1}", requestMessage.MsgId, DateTime.Now.Ticks); return(faultTolerantResponseMessage); } else { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:http://sdk.weixin.senparc.com"); responseMessage.Content = result.ToString(); } return(responseMessage); }
public ActionResult Index(string url, string token, RequestMsgType requestType, Event?eventType, bool testConcurrence, int testConcurrenceCount, bool testEncrypt, string encodingAESKey, string appId) { using (MemoryStream ms = new MemoryStream()) { var requestMessaageDoc = GetrequestMessaageDoc(/*url, token,*/ requestType, eventType); requestMessaageDoc.Save(ms); ms.Seek(0, SeekOrigin.Begin); string msgSigature = null; var timeStamp = SystemTime.NowTicks.ToString(); var nonce = (SystemTime.NowTicks * 2).ToString(); string encryptTypeAll = null; string openIdAll = null; //对请求消息进行加密 if (testEncrypt) { try { var openId = requestMessaageDoc.Root.Element("FromUserName").Value; var toUserName = requestMessaageDoc.Root.Element("ToUserName").Value; WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(token, encodingAESKey, appId); string finalResponseXml = null; var ret = msgCrype.EncryptRequestMsg(requestMessaageDoc.ToString(), timeStamp, nonce, toUserName, ref finalResponseXml, ref msgSigature); if (ret == 0) { requestMessaageDoc = XDocument.Parse(finalResponseXml);//赋值最新的加密信息 openIdAll = $"openid={openId}"; encryptTypeAll = "&encrypt_type=aes"; } } catch (Exception ex) { var data = new { Success = false, LoadTime = "N/A", Result = "发生错误:" + ex.ToString() }; return(Json(data, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })); throw; } //Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog("模拟测试-加密消息:", requestMessaageDoc?.ToString()); } var sigature = CheckSignature.GetSignature(timeStamp, nonce, token); url += url.Contains("?") ? "&" : "?"; url += $"signature={sigature}&timeStamp={timeStamp}&nonce={nonce}&msg_signature={msgSigature}{encryptTypeAll}{openIdAll}"; //参数如:signature=330ed3b64e363dc876f35e54a79e59b48739f567×tamp=1570075722&nonce=863153744&openid=olPjZjsXuQPJoV0HlruZkNzKc91E&encrypt_type=aes&msg_signature=71dc359205a4660bc3b3046b643452c994b5897d var dt1 = SystemTime.Now; try { dt1 = SystemTime.Now; if (testConcurrence) { //异步方法 testConcurrenceCount = testConcurrenceCount > 30 ? 30 : testConcurrenceCount;//设定最高限额 //模拟并发请求 List <Task <string> > taskList = new List <Task <string> >(); for (int i = 0; i < testConcurrenceCount; i++) { var task = TestAsyncTask(url, token, requestMessaageDoc, autoFillUrlParameters: false, index: i, sleepMillionSeconds: 0); taskList.Add(task); } Task.WaitAll(taskList.ToArray(), 1500 * 10); } else { //同步方法,立即发送 _responseMessageXml = MessageAgent.RequestXml(null, url, token, requestMessaageDoc.ToString(), autoFillUrlParameters: false); } if (string.IsNullOrEmpty(_responseMessageXml)) { _responseMessageXml = "返回消息为空,可能已经被去重。\r\nMsgId相同的连续消息将被自动去重。"; } var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance(); var data = new { Success = true, LoadTime = SystemTime.DiffTotalMS(dt1, "f4"), Result = _responseMessageXml, CacheType = cache.GetType().Name, ConcurrenceCount = testConcurrenceCount }; return(Json(data, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })); } catch (Exception ex) { var msg = string.Format("{0}\r\n{1}\r\n{2}", ex.Message, null, ex.InnerException != null ? ex.InnerException.Message : null); return(Json(new { Success = false, Result = msg }, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })); } } }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //说明:实际项目中这里的逻辑可以交给Service处理具体信息 //参考OnLocationRequest方法或 /Service/LocationSercice.cs var defaultResponseMessage = base.CreateResponseMessage <ResponseMessageText>(); var requestHandler = requestMessage.StartHandler() //关键字不区分大小写,按照顺序匹配成功后将不再运行下面的逻辑 .Keyword("约束", () => { defaultResponseMessage.Content = @"您正在进行微信内置浏览器约束判断测试。 您可以:<a href=""http://sdk.weixin.senparc.com/FilterTest/"">点击这里</a> 进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/), 如果在微信外打开将直接返回文字。 或:<a href=""http://sdk.weixin.senparc.com/FilterTest/Redirect"">点击这里</a> 进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/Redirect), 如果在微信外打开将重定向一次URL。"; return(defaultResponseMessage); }). //匹配任一关键字 Keywords(new[] { "托管", "代理" }, () => { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var agentXml = RequestDocument.ToString(); #region 暂时转发到SDK线上Demo agentUrl = "http://sdk.weixin.senparc.com/weixin"; //agentToken = WebConfigurationManager.AppSettings["WeixinToken"];//Token //修改内容,防止死循环 var agentDoc = XDocument.Parse(agentXml); agentDoc.Root.Element("Content").SetValue("代理转发文字:" + requestMessage.Content); agentDoc.Root.Element("CreateTime").SetValue(DateTimeHelper.GetWeixinDateTime(DateTime.Now)); //修改时间,防止去重 agentDoc.Root.Element("MsgId").SetValue("123"); //防止去重 agentXml = agentDoc.ToString(); #endregion var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, agentXml); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有WeiweihiKey,可以直接使用下面的这个MessageAgent.RequestWeiweihiXml()方法。 * WeiweihiKey专门用于对接www.weiweihi.com平台,获取方式见:https://www.weiweihi.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestWeiweihiXml(weiweihiKey, RequestDocument.ToString());//获取Weiweihi返回的XML DateTime dt2 = DateTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ var msg = string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); var agentResponseMessage = responseXml.CreateResponseMessage(); if (agentResponseMessage is ResponseMessageText) { (agentResponseMessage as ResponseMessageText).Content += msg; } else if (agentResponseMessage is ResponseMessageNews) { (agentResponseMessage as ResponseMessageNews).Articles[0].Description += msg; } return(agentResponseMessage); //可能出现多种类型,直接在这里返回 }) .Keywords(new[] { "退出" }, () => { defaultResponseMessage.Content = "您已经退出【威尔汽车租赁】的测试程序。"; return(defaultResponseMessage); }) .Keyword("OPEN", () => { var openResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageNews>(); openResponseMessage.Articles.Add(new Article() { Title = "开放平台微信授权测试", Description = @"点击进入Open授权页面。授权之后,您的微信所收到的消息将转发到第三方(威尔汽车租赁)的服务器上,并获得对应的回复。测试完成后,您可以登陆公众号后台取消授权。", Url = "http://sdk.weixin.senparc.com/OpenOAuth/JumpToMpOAuth" }); return(openResponseMessage); }) .Keyword("错误", () => { var errorResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); //因为没有设置errorResponseMessage.Content,所以这小消息将无法正确返回。 return(errorResponseMessage); }) .Keyword("容错", () => { Thread.Sleep(4900); //故意延时1.5秒,让微信多次发送消息过来,观察返回结果 var faultTolerantResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); faultTolerantResponseMessage.Content = string.Format("测试容错,MsgId:{0},Ticks:{1}", requestMessage.MsgId, DateTime.Now.Ticks); return(faultTolerantResponseMessage); }) .Keyword("TM", () => { var openId = requestMessage.FromUserName; var checkCode = Guid.NewGuid().ToString("n").Substring(0, 3); //为了防止openId泄露造成骚扰,这里启用验证码 TemplateMessageCollection[checkCode] = openId; defaultResponseMessage.Content = string.Format(@"新的验证码为:{0},请在网页上输入。网址:http://sdk.weixin.senparc.com/AsyncMethods", checkCode); return(defaultResponseMessage); }) .Keyword("OPENID", () => { var openId = requestMessage.FromUserName; //获取OpenId var userInfo = UserApi.Info(appId, openId, Language.zh_CN); defaultResponseMessage.Content = string.Format( "您的OpenID为:{0}\r\n昵称:{1}\r\n性别:{2}\r\n地区(国家/省/市):{3}/{4}/{5}\r\n关注时间:{6}\r\n关注状态:{7}", requestMessage.FromUserName, userInfo.nickname, (Sex)userInfo.sex, userInfo.country, userInfo.province, userInfo.city, DateTimeHelper.GetDateTimeFromXml(userInfo.subscribe_time), userInfo.subscribe); return(defaultResponseMessage); }) .Keyword("EX", () => { var ex = new WeixinException("openid:" + requestMessage.FromUserName + ":这是一条测试异常信息"); //回调过程在global的ConfigWeixinTraceLog()方法中 defaultResponseMessage.Content = "请等待异步模板消息发送到此界面上(自动延时数秒)。\r\n当前时间:" + DateTime.Now.ToString(); return(defaultResponseMessage); }) .Keyword("MUTE", () => //不回复任何消息 { //方案一: return(new SuccessResponseMessage()); //方案二: var muteResponseMessage = base.CreateResponseMessage <ResponseMessageNoResponse>(); return(muteResponseMessage); //方案三: base.TextResponseMessage = "success"; return(null); }) .Keyword("JSSDK", () => { defaultResponseMessage.Content = "点击打开:http://sdk.weixin.senparc.com/WeixinJsSdk"; return(defaultResponseMessage); }) //Default不一定要在最后一个 .Default(() => { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToString("HH:mm:ss"), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:http://sdk.weixin.senparc.com"); defaultResponseMessage.Content = result.ToString(); return(defaultResponseMessage); }) //“一次订阅消息”接口测试 .Keyword("订阅", () => { defaultResponseMessage.Content = "点击打开:https://sdk.weixin.senparc.com/SubscribeMsg"; return(defaultResponseMessage); }) //正则表达式 .Regex(@"^\d+#\d+$", () => { defaultResponseMessage.Content = string.Format("您输入了:{0},符合正则表达式:^\\d+#\\d+$", requestMessage.Content); return(defaultResponseMessage); }); return(requestHandler.GetResponseMessage() as IResponseMessageBase); }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using Senparc.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 var responseMessage = base.CreateResponseMessage <ResponseMessageText>(); if (requestMessage.Content == null) { } else if (requestMessage.Content == "约束") { responseMessage.Content = "<a href=\"http://weixin.senparc.com/FilterTest/\">点击这里</a>进行客户端约束测试(地址:http://weixin.senparc.com/FilterTest/)。"; } else if (requestMessage.Content == "托管" || requestMessage.Content == "代理") { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, RequestDocument.ToString()); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有WeiweihiKey,可以直接使用下面的这个MessageAgent.RequestWeiweihiXml()方法。 * WeiweihiKey专门用于对接www.weiweihi.com平台,获取方式见:http://www.weiweihi.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestWeiweihiXml(weiweihiKey, RequestDocument.ToString());//获取Weiweihi返回的XML DateTime dt2 = DateTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ responseMessage = responseXml.CreateResponseMessage() as ResponseMessageText; responseMessage.Content += string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); } else if (requestMessage.Content == "测试" || requestMessage.Content == "退出") { /* * 这是一个特殊的过程,此请求通常来自于微微嗨(http://www.weiweihi.com)的“盛派网络小助手”应用请求(http://www.weiweihi.com/User/App/Detail/1), * 用于演示微微嗨应用商店的处理过程,由于微微嗨的应用内部可以单独设置对话过期时间,所以这里通常不需要考虑对话状态,只要做最简单的响应。 */ if (requestMessage.Content == "测试") { //进入APP测试 responseMessage.Content = "您已经进入【盛派网络小助手】的测试程序,请发送任意信息进行测试。发送文字【退出】退出测试对话。10分钟内无任何交互将自动退出应用对话状态。"; } else { //退出APP测试 responseMessage.Content = "您已经退出【盛派网络小助手】的测试程序。"; } } else if (requestMessage.Content == "AsyncTest") { //异步并发测试(提供给单元测试使用) DateTime begin = DateTime.Now; int t1, t2, t3; System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3); System.Threading.ThreadPool.GetMaxThreads(out t2, out t3); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4)); DateTime end = DateTime.Now; var thread = System.Threading.Thread.CurrentThread; responseMessage.Content = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, HttpContext.Current != null ? HttpContext.Current.ApplicationInstance.GetHashCode() : -1, begin, end, t2 - t1 ); } else { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:http://weixin.senparc.com"); responseMessage.Content = result.ToString(); } return(responseMessage); }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs #region 书中例子 //if (requestMessage.Content == "你好") //{ // var responseMessage = base.CreateResponseMessage<ResponseMessageNews>(); // var title = "Title"; // var description = "Description"; // var picUrl = "PicUrl"; // var url = "Url"; // responseMessage.Articles.Add(new Article() // { // Title = title, // Description = description, // PicUrl = picUrl, // Url = url // }); // return responseMessage; //} //else if (requestMessage.Content == "Senparc") //{ // //相似处理逻辑 //} //else //{ // //... //} #endregion //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using Senparc.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 var responseMessage = base.CreateResponseMessage <ResponseMessageText>(); if (requestMessage.Content == null) { } else if (requestMessage.Content == "约束") { responseMessage.Content = @"您正在进行微信内置浏览器约束判断测试。您可以: <a href=""http://sdk.weixin.senparc.com/FilterTest/"">点击这里</a>进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/),如果在微信外打开将直接返回文字。 或: <a href=""http://sdk.weixin.senparc.com/FilterTest/Redirect"">点击这里</a>进行客户端约束测试(地址:http://sdk.weixin.senparc.com/FilterTest/Redirect),如果在微信外打开将重定向一次URL。"; } else if (requestMessage.Content == "托管" || requestMessage.Content == "代理") { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var agentXml = RequestDocument.ToString(); #region 暂时转发到SDK线上Demo agentUrl = "http://sdk.weixin.senparc.com/weixin"; agentToken = WebConfigurationManager.AppSettings["WeixinToken"];//Token //修改内容,防止死循环 var agentDoc = XDocument.Parse(agentXml); agentDoc.Root.Element("Content").SetValue("代理转发文字:" + requestMessage.Content); agentDoc.Root.Element("CreateTime").SetValue(DateTimeHelper.GetWeixinDateTime(DateTime.Now)); //修改时间,防止去重 agentDoc.Root.Element("MsgId").SetValue("123"); //防止去重 agentXml = agentDoc.ToString(); #endregion var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, agentXml); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有WeiweihiKey,可以直接使用下面的这个MessageAgent.RequestWeiweihiXml()方法。 * WeiweihiKey专门用于对接www.weiweihi.com平台,获取方式见:https://www.weiweihi.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestWeiweihiXml(weiweihiKey, RequestDocument.ToString());//获取Weiweihi返回的XML DateTime dt2 = DateTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ var msg = string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); var agentResponseMessage = responseXml.CreateResponseMessage(); if (agentResponseMessage is ResponseMessageText) { (agentResponseMessage as ResponseMessageText).Content += msg; } else if (agentResponseMessage is ResponseMessageNews) { (agentResponseMessage as ResponseMessageNews).Articles[0].Description += msg; } return(agentResponseMessage);//可能出现多种类型,直接在这里返回 } else if (requestMessage.Content == "测试" || requestMessage.Content == "退出") { /* * 这是一个特殊的过程,此请求通常来自于微微嗨(http://www.weiweihi.com)的“盛派网络小助手”应用请求(https://www.weiweihi.com/User/App/Detail/1), * 用于演示微微嗨应用商店的处理过程,由于微微嗨的应用内部可以单独设置对话过期时间,所以这里通常不需要考虑对话状态,只要做最简单的响应。 */ if (requestMessage.Content == "测试") { //进入APP测试 responseMessage.Content = "您已经进入【盛派网络小助手】的测试程序,请发送任意信息进行测试。发送文字【退出】退出测试对话。10分钟内无任何交互将自动退出应用对话状态。"; } else { //退出APP测试 responseMessage.Content = "您已经退出【盛派网络小助手】的测试程序。"; } } else if (requestMessage.Content == "AsyncTest") { //异步并发测试(提供给单元测试使用) DateTime begin = DateTime.Now; int t1, t2, t3; System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3); System.Threading.ThreadPool.GetMaxThreads(out t2, out t3); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4)); DateTime end = DateTime.Now; var thread = System.Threading.Thread.CurrentThread; responseMessage.Content = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, HttpContext.Current != null ? HttpContext.Current.ApplicationInstance.GetHashCode() : -1, begin, end, t2 - t1 ); } else if (requestMessage.Content.ToUpper() == "OPEN") { var openResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageNews>(); openResponseMessage.Articles.Add(new Article() { Title = "开放平台微信授权测试", Description = @"点击进入Open授权页面。 授权之后,您的微信所收到的消息将转发到第三方(盛派网络小助手)的服务器上,并获得对应的回复。 测试完成后,您可以登陆公众号后台取消授权。", Url = "http://sdk.weixin.senparc.com/OpenOAuth/JumpToMpOAuth" }); return(openResponseMessage); } else if (requestMessage.Content == "错误") { var errorResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); //因为没有设置errorResponseMessage.Content,所以这小消息将无法正确返回。 return(errorResponseMessage); } else if (requestMessage.Content == "容错") { Thread.Sleep(1500);//故意延时1.5秒,让微信多次发送消息过来,观察返回结果 var faultTolerantResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageText>(); faultTolerantResponseMessage.Content = string.Format("测试容错,MsgId:{0},Ticks:{1}", requestMessage.MsgId, DateTime.Now.Ticks); return(faultTolerantResponseMessage); } else if (requestMessage.Content.ToUpper() == "TM")//异步模板消息设置 { var openId = requestMessage.FromUserName; var checkCode = Guid.NewGuid().ToString("n").Substring(0, 3);//为了防止openId泄露造成骚扰,这里启用验证码 TemplateMessageCollection[checkCode] = openId; responseMessage.Content = string.Format(@"新的验证码为:{0},请在网页上输入。网址:http://sdk.weixin.senparc.com/AsyncMethods", checkCode); } else if (requestMessage.Content.ToUpper() == "OPENID") //返回OpenId及用户信息 { var openId = requestMessage.FromUserName; //获取OpenId var userInfo = AdvancedAPIs.UserApi.Info(appId, openId, Language.zh_CN); responseMessage.Content = string.Format( "您的OpenID为:{0}\r\n昵称:{1}\r\n性别:{2}\r\n地区(国家/省/市):{3}/{4}/{5}\r\n关注时间:{6}\r\n关注状态:{7}", requestMessage.FromUserName, userInfo.nickname, (Sex)userInfo.sex, userInfo.country, userInfo.province, userInfo.city, DateTimeHelper.GetDateTimeFromXml(userInfo.subscribe_time), userInfo.subscribe); } else if (requestMessage.Content.ToUpper() == "EX") { var ex = new WeixinException("openid:" + requestMessage.FromUserName + ":这是一条测试异常信息");//回调过程在global的ConfigWeixinTraceLog()方法中 responseMessage.Content = "请等待异步模板消息发送到此界面上(自动延时数秒)。\r\n当前时间:" + DateTime.Now.ToString(); } else if (requestMessage.Content.ToUpper() == "MUTE") { return(new SuccessResponseMessage()); base.TextResponseMessage = "success"; responseMessage = null; } else { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:http://sdk.weixin.senparc.com"); responseMessage.Content = result.ToString(); } return(responseMessage); }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using ChainClouds.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 var responseMessage = base.CreateResponseMessage <ResponseMessageText>(); if (requestMessage.Content == null) { } else if (requestMessage.Content == "约束") { responseMessage.Content = @"您正在进行微信内置浏览器约束判断测试。您可以: <a href=""http://open.chainclouds.com/FilterTest/"">点击这里</a>进行客户端约束测试(地址:http://open.chainclouds.com/FilterTest/),如果在微信外打开将直接返回文字。 或: <a href=""http://open.chainclouds.com/FilterTest/Redirect"">点击这里</a>进行客户端约束测试(地址:http://open.chainclouds.com/FilterTest/Redirect),如果在微信外打开将重定向一次URL。"; } else if (requestMessage.Content == "托管" || requestMessage.Content == "代理") { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, RequestDocument.ToString()); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有ChaincloudsKey,可以直接使用下面的这个MessageAgent.RequestChaincloudsXml()方法。 * ChaincloudsKey专门用于对接www.chainclouds.com平台,获取方式见:http://www.chainclouds.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestChaincloudsXml(chaincloudsKey, RequestDocument.ToString());//获取Chainclouds返回的XML DateTime dt2 = DateTime.Now; //计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ var msg = string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); var agentResponseMessage = responseXml.CreateResponseMessage(); if (agentResponseMessage is ResponseMessageText) { (agentResponseMessage as ResponseMessageText).Content += msg; } else if (agentResponseMessage is ResponseMessageNews) { (agentResponseMessage as ResponseMessageNews).Articles[0].Description += msg; } return(agentResponseMessage);//可能出现多种类型,直接在这里返回 } else if (requestMessage.Content == "测试" || requestMessage.Content == "退出") { /* * 这是一个特殊的过程,此请求通常来自于“连锁掌柜小助手”应用请求(http://www.chainclouds.com/User/App/Detail/1), * 用于演示连锁掌柜应用商店的处理过程,由于连锁掌柜的应用内部可以单独设置对话过期时间,所以这里通常不需要考虑对话状态,只要做最简单的响应。 */ if (requestMessage.Content == "测试") { //进入APP测试 responseMessage.Content = "您已经进入【连锁掌柜小助手】的测试程序,请发送任意信息进行测试。发送文字【退出】退出测试对话。10分钟内无任何交互将自动退出应用对话状态。"; } else { //退出APP测试 responseMessage.Content = "您已经退出【连锁掌柜小助手】的测试程序。"; } } else if (requestMessage.Content == "AsyncTest") { //异步并发测试(提供给单元测试使用) DateTime begin = DateTime.Now; int t1, t2, t3; System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3); System.Threading.ThreadPool.GetMaxThreads(out t2, out t3); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4)); DateTime end = DateTime.Now; var thread = System.Threading.Thread.CurrentThread; responseMessage.Content = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}", thread.ManagedThreadId, HttpContext.Current != null ? HttpContext.Current.ApplicationInstance.GetHashCode() : -1, begin, end, t2 - t1 ); } else if (requestMessage.Content == "open") { var openResponseMessage = requestMessage.CreateResponseMessage <ResponseMessageNews>(); openResponseMessage.Articles.Add(new Article() { Title = "开放平台微信授权测试", Description = @"点击进入Open授权页面。 授权之后,您的微信所收到的消息将转发到第三方(连锁掌柜小助手)的服务器上,并获得对应的回复。 测试完成后,您可以登陆公众号后台取消授权。", Url = "http://open.chainclouds.com/OpenOAuth/JumpToMpOAuth" }); return(openResponseMessage); } else { //#region 老接口调用 //var keywordDAO = new WKeywordReplyDAO(this.LoggingSession); ////var ds = keywordDAO.GetMaterialByKeyword(content); //var ds = keywordDAO.GetMaterialByKeywordJermyn(requestMessage.Content, requestMessage.ToUserName, 1); //int keywordType = 1; //#region 如果没有关键字回复,给予自动回复内容 //if (ds == null || ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0) //{ // ds = keywordDAO.GetMaterialByKeywordJermyn(requestMessage.Content, requestMessage.ToUserName, 3); // keywordType = 3; //} //#endregion //#region 如果回复,调用老的接口 //if (ds == null || ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0) //{ // //HandlerTextOld(); // //return;//执行 完老的发送信息的方法,就直接跳出请去,不往下走了**** //} //#endregion //var resultinfo = new StringBuilder(); //if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) //{ // string Text = ds.Tables[0].Rows[0]["Text"].ToString(); //素材类型 // string ReplyId = ds.Tables[0].Rows[0]["ReplyId"].ToString(); //素材ID // string typeId = ds.Tables[0].Rows[0]["ReplyType"].ToString(); //素材ID // resultinfo.AppendLine(Text); // //BaseService.WriteLogWeixin("ReplyId:" + ReplyId); // //BaseService.WriteLogWeixin("typeId:" + typeId); // //switch (typeId) // //{ // // case MaterialType.TEXT: //回复文字消息 // // //ReplyText(materialId); // // ReplyTextJermyn(Text); // // break; // // case MaterialType.IMAGE_TEXT: //回复图文消息 // // //ReplyNews(materialId); // // ReplyNewsJermyn(ReplyId, keywordType, 1); // // break; // // default: // // break; // //} //} //#endregion var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine( "您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。"); //result = resultinfo.Length > 0 ? resultinfo : result; responseMessage.Content = result.ToString(); } return(responseMessage); }
/// <summary> /// 处理文字请求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs //方法一(v0.1),此方法调用太过繁琐,已过时(但仍是所有方法的核心基础),建议使用方法二到四 //var responseMessage = // ResponseMessageBase.CreateFromRequestMessage(RequestMessage, ResponseMsgType.Text) as // ResponseMessageText; //方法二(v0.4) //var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage); //方法三(v0.4),扩展方法,需要using Senparc.Weixin.MP.Helpers; //var responseMessage = RequestMessage.CreateResponseMessage<ResponseMessageText>(); //方法四(v0.6+),仅适合在HandlerMessage内部使用,本质上是对方法三的封装 //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。 var responseMessage = base.CreateResponseMessage <ResponseMessageText>(); if (requestMessage.Content == "约束") { responseMessage.Content = "<a href=\"http://weixin.senparc.com/FilterTest/\">点击这里</a>进行客户端约束测试(地址:http://weixin.senparc.com/FilterTest/)。"; } if (requestMessage.Content == "托管" || requestMessage.Content == "代理") { //开始用代理托管,把请求转到其他服务器上去,然后拿回结果 //甚至也可以将所有请求在DefaultResponseMessage()中托管到外部。 DateTime dt1 = DateTime.Now; //计时开始 var responseXml = MessageAgent.RequestXml(this, agentUrl, agentToken, RequestDocument.ToString()); //获取返回的XML //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); /* 如果有SouideaKey,可以直接使用下面的这个MessageAgent.RequestSouideaXml()方法。 * SouideaKey专门用于对接www.souidea.com平台,获取方式见:http://www.souidea.com/ApiDocuments/Item/25#51 */ //var responseXml = MessageAgent.RequestSouideaXml(souideaKey, RequestDocument.ToString());//获取Souidea返回的XML DateTime dt2 = DateTime.Now;//计时结束 //转成实体。 /* 如果要写成一行,可以直接用: * responseMessage = MessageAgent.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); * 或 * */ responseMessage = responseXml.CreateResponseMessage() as ResponseMessageText; responseMessage.Content += string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); } else { var result = new StringBuilder(); result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字类型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine("您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:http://weixin.senparc.com"); responseMessage.Content = result.ToString(); } return(responseMessage); }