微信开放平台全网发布时,检测失败 —— C#

主要就是三个:返回API文本消息,返回普通文本消息,发送事件消息   --会出现失败的情况

(后续补充说明:出现检测出错,不一定是代码出现了问题,也有可能是1.微信方面检测时出现服务器请求失败,2.我们程序反应过慢,服务器处理超过微信方面的接收时长,导致微信方面未接收信息,报错

 

今天大概一下午坐着查这个了,眼睛疼得要命

图忘记截了,现在只剩下成功的图了,明天大概就会有结果了

先把当前成功的代码发布上来

用的C# MVC

public ActionResult Receive(string timestamp, string nonce, string encrypt_type)
        {
            Log4NetHelper.Info("merchant message recive");
            var encryptMsg = string.Empty;
            try
            {
                string appid = "";
                if (!string.IsNullOrEmpty(Request["appid"]))
                {
                    appid = Request["appid"].Substring(1);
                }
                WeixinMessage message = null;
                var safeMode = Request.QueryString.Get("encrypt_type") == "aes";
                using (var streamReader = new StreamReader(Request.InputStream))
                {
                    var decryptMsg = string.Empty;
                    var msg = streamReader.ReadToEnd();
                    #region 解密
                    if (safeMode)
                    {
                        var msg_signature = Request.QueryString.Get("msg_signature");
                        var wxBizMsgCrypt = new WXBizMsgCrypt(
                             CachedConfigContext.Current.WeixinOpenConfig.Token,
                             CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,
                             CachedConfigContext.Current.WeixinOpenConfig.AppID);
                        var ret = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decryptMsg);
                        if (ret != 0)//解密失败
                        {
                            //TODO:开发者解密失败的业务处理逻辑
                            //注意:本demo用log4net记录此信息,你可以用其他方法
                            Log4NetHelper.Info(string.Format("decrypt message return {0}, request body {1}", ret, msg));
                            WriteTxt.RecodeBug(string.Format("1商户接收信息,解密失败:decrypt message return {0}, request body {1}", ret, msg), "/merchant_receive.txt");
                        }
                    }
                    else
                    {
                        decryptMsg = msg;
                    }
                    #endregion
                    //将传入的数据流转成对象
                    message = AcceptMessageAPI.Parse(decryptMsg);
                }

                #region 全网发布流进入 appid值为wx570bc396a51b8ff8
                if (appid.Contains("wx570bc396a51b8ff8"))//微信官方测试账号,用来全网发布测试的
                {
                    var openId = message.Body.FromUserName.Value;
                    var myUserName = message.Body.ToUserName.Value;
                    WriteTxt.RecodeBug(string.Format("1官方微信测试账号进入 event={0},openID={1}, myUserName={2}", message.Type, openId, myUserName), "/merchant_receive.txt");
                    #region 全网发布event
                    if (message.Type == WeixinMessageType.Event)
                    {
                        string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +
                                                   "<FromUserName><![CDATA[{1}]]></FromUserName>" +
                                                   "<CreateTime>{2}</CreateTime>" +
                                                   "<MsgType><![CDATA[text]]></MsgType>" +
                                                   "<Content><![CDATA[{3}]]></Content></xml>",
                                                   openId, myUserName, Util.CreateTimestamp(), message.Body.Event.Value.ToString() + "from_callback");

                        WriteTxt.RecodeBug(string.Format("2全网发布事件返回内容content={0},safeMode={1}", content, safeMode), "/merchant_receive.txt");
                        #region 加密
                        if (safeMode)
                        {
                            var msg_signature = Request.QueryString.Get("msg_signature");
                            var wxBizMsgCrypt = new WXBizMsgCrypt(
                                    CachedConfigContext.Current.WeixinOpenConfig.Token,
                                     CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,
                                     CachedConfigContext.Current.WeixinOpenConfig.AppID);
                            var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);
                            if (ret != 0)//加密失败
                            {
                                //TODO:开发者加密失败的业务处理逻辑
                                //Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));
                                WriteTxt.RecodeBug(string.Format("2商户接收信息,加密失败:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                            }
                            else
                            {
                                WriteTxt.RecodeBug(string.Format("2商户接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                            }

                        }
                        else
                        {
                            encryptMsg = content;
                        }
                        #endregion
                        return new ContentResult
                        {
                            Content = encryptMsg,
                            ContentType = "text/xml",
                            ContentEncoding = System.Text.UTF8Encoding.UTF8
                        };
                    } 
                    #endregion
                    #region 全网发布text
                    else if (message.Type == WeixinMessageType.Text)
                    {
                        string con = message.Body.Content.Value.ToString();
                        WriteTxt.RecodeBug(string.Format("2全网发布Text中的content={0},\"TESTCOMPONENT_MSG_TYPE_TEXT\".Equals(con)={1}", con, "TESTCOMPONENT_MSG_TYPE_TEXT".Equals(con)), "/merchant_receive.txt");

                        //全网发布中,立即返回信息到粉丝
                        #region 全网发布text,立即返回
                        if ("TESTCOMPONENT_MSG_TYPE_TEXT".Equals(con))
                        {
                            string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +
                                                   "<FromUserName><![CDATA[{1}]]></FromUserName>" +
                                                   "<CreateTime>{2}</CreateTime>" +
                                                   "<MsgType><![CDATA[text]]></MsgType>" +
                                                   "<Content><![CDATA[{3}]]></Content></xml>",
                                                   openId, myUserName, Util.CreateTimestamp(), "TESTCOMPONENT_MSG_TYPE_TEXT_callback");
                            WriteTxt.RecodeBug(string.Format("3全网发布TEXT 立即回复 content={0},safeMode={1}", content, safeMode), "/merchant_receive.txt");

                            #region 加密
                            if (safeMode)
                            {
                                var msg_signature = Request.QueryString.Get("msg_signature");
                                var wxBizMsgCrypt = new WXBizMsgCrypt(
                                        CachedConfigContext.Current.WeixinOpenConfig.Token,
                                         CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,
                                         CachedConfigContext.Current.WeixinOpenConfig.AppID);
                                var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);
                                if (ret != 0)//加密失败
                                {
                                    //TODO:开发者加密失败的业务处理逻辑
                                    //Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));
                                    WriteTxt.RecodeBug(string.Format("2商户接收信息,加密失败:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                                }
                                else
                                {
                                    WriteTxt.RecodeBug(string.Format("2商户接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                                }
                            }
                            else
                            {
                                encryptMsg = content;
                            }
                            #endregion
                            //直接返回不太对,直接将加密判断给领过来了(上面)
                            return new ContentResult
                            {
                                Content = encryptMsg,
                                ContentType = "text/xml",
                                ContentEncoding = System.Text.UTF8Encoding.UTF8
                            };
                        }
                        #endregion
                        #region 全网发布text 客服接口发送
                        else
                        {
                            string content = message.Body.Content.Value.ToString();
                            WriteTxt.RecodeBug(string.Format("3content={0}", content), "/merchant_receive.txt");
                            if (content.StartsWith("QUERY_AUTH_CODE", true, System.Globalization.CultureInfo.CurrentCulture))
                            {
                                string temp = content.Split(':')[1];
                                WriteTxt.RecodeBug(string.Format("QUERY_AUTH_CODE拿到的值={0}", temp), "/merchant_receive.txt");
                                HttpContext.Response.Write("");
                                WriteTxt.RecodeBug(string.Format("全网发布text客服回复start"), "/merchant_receive.txt");
                                var ourPublic = ServiceContext.Current.WeixinOpenService.GetWxSetting();
                                string componentAccessToken = ourPublic.ComponentAccessToken;
                                QueryAuthData data = Qxun.Framework.Weixin.Open.ComponentAPI.QueryAuthorization(componentAccessToken, CachedConfigContext.Current.WeixinOpenConfig.AppID, temp);
                                ReplayActiveMessageAPI.RepayText(data.authorization_info.authorizer_access_token, openId, temp + "_from_api");
                                WriteTxt.RecodeBug(string.Format("4全网发布text客服回复end"), "/merchant_receive.txt");
                                return Content("success");
                            }
                        }
                        #endregion
                    } 
                    #endregion
                }
                #endregion

                //进入消息获取分析方法 Execute
                var response = WeixinExecutor.Execute(message, mpn.MerchantID);

                #region 加密
                if (safeMode)
                {
                    var msg_signature = Request.QueryString.Get("msg_signature");
                    var wxBizMsgCrypt = new WXBizMsgCrypt(
                            CachedConfigContext.Current.WeixinOpenConfig.Token,
                             CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,
                             CachedConfigContext.Current.WeixinOpenConfig.AppID);
                    var ret = wxBizMsgCrypt.EncryptMsg(response, timestamp, nonce, ref encryptMsg);
                    if (ret != 0)//加密失败
                    {
                        //TODO:开发者加密失败的业务处理逻辑
                        //Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));
                        WriteTxt.RecodeBug(string.Format("2商户接收信息,加密失败:encrypt message return {0}, response body {1}", ret, response), "/merchant_receive.txt");
                    }
                }
                else
                {
                    encryptMsg = response;
                }
                #endregion
            }
            catch (Exception e)
            {
                WriteTxt.RecodeBug(string.Format("10Exception:商户接受信息,出现异常:{0}", e.Message), "/merchant_receive.txt");
            }

            return new ContentResult
            {
                Content = encryptMsg,
                ContentType = "text/xml",
                ContentEncoding = System.Text.UTF8Encoding.UTF8
            };
        }
微信全网发布相关代码

官网文档说明:

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318611&lang=zh_CN

官网上的总结主要有以下几点:

1.微信会拿一个公众号来进行测试,其appid的值就是下面这个了,主要用来和原来的代码进行区分,不要将自己正常的运行也给弄进去了

  1. (1)appid: wx570bc396a51b8ff8

  2. (2)Username: gh_3c884a361561

2.这里的检测有三种,这里,由于百度的时候,有些都说不要加密,这一点我也不好直接说不对,不过之前有一次使用的时候,没有经过加密判断,就失败了

var safeMode = Request.QueryString.Get("encrypt_type") == "aes";
string encryptMsg="";
#region 加密
                        if (safeMode)
                        {
                            var msg_signature = Request.QueryString.Get("msg_signature");
                            var wxBizMsgCrypt = new WXBizMsgCrypt(
                                    CachedConfigContext.Current.WeixinOpenConfig.Token,
                                     CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,
                                     CachedConfigContext.Current.WeixinOpenConfig.AppID);
                            var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);
                            if (ret != 0)//加密失败
                            {
                                //TODO:开发者加密失败的业务处理逻辑
                                //Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));
                                WriteTxt.RecodeBug(string.Format("2商户接收信息,加密失败:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                            }
                            else
                            {
                                WriteTxt.RecodeBug(string.Format("2商户接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");
                            }

                        }
                        else
                        {
                            encryptMsg = content;
                        }
                        #endregion
判断是否加密

 

第一种:推送事件消息,返回的信息Content值得是

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>

接收的Event的值+ "from_callback"

传回去的content 格式 ,我这边的设置,因为传回去的都是text类型,推送普通文本信息也是text的

 

string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +
                                                   "<FromUserName><![CDATA[{1}]]></FromUserName>" +
                                                   "<CreateTime>{2}</CreateTime>" +
                                                   "<MsgType><![CDATA[text]]></MsgType>" +
                                                   "<Content><![CDATA[{3}]]></Content></xml>",
                                                   openId, myUserName, Util.CreateTimestamp(), message.Body.Event.Value.ToString() + "from_callback");

 

return new ContentResult
            {
                Content = content,
                ContentType = "text/xml",
                ContentEncoding = System.Text.UTF8Encoding.UTF8
            };

 

微信事件推送链接:

https://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html

第二种:返回普通文本消息

这个传进来和传回去的内容都是固定的,传入的值会是"TESTCOMPONENT_MSG_TYPE_TEXT",传回去的值必须是"TESTCOMPONENT_MSG_TYPE_TEXT_callback"

至于为什么固定了传入的值,是为了区分下面那种客服回复的情况。所以这种情况就要判断一下是否content是否等于TESTCOMPONENT_MSG_TYPE_TEXT,contains也是可以的

这个返回信息和上面那个差不多

第三种:返回API文本消息

传入的Content会是:QUERY_AUTH_CODE:$query_auth_code$ 这样的,$query_auth_code$是要用的的值,需要截取出来。用string.Split(':')[1]就可以了,反正微信那边传过来都是绝对符合格式的

因为这个需要先返回个空字符串,c#这边用这种写法就可以了。当然不能在这里就给return了,我们还得继续那客服发信息的接口呢。

需要拿到的有:我们公众号作为被授权方的 ComponentAccessToken,我们公众号的appid,以及之前截取的$query_auth_code$这个拿到的值

调用https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={0}这个接口,post传值 :component_appid和authorization_code —— 这个是用来获取 authorization_info授权信息内的authorizer_access_token的

微信API文档地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=fdc4e8827bb64f7892affcca13cc451abc6581df&lang=zh_CN

 

拿到authorizer_access_token之后,就可以调用客服发送信息的接口了https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}

 

客服发送信息的官方接口:https://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html

以上三种就差不多了

当然,这些的前提是,项目测试授权正常。

 

总觉得没有失败的图不好,就跑去人家那边截了个图过来

 

 

上面的都是2016-07-27晚上八点左右写的

 

今天去查看了一下,已经发布成功了,过了十多个小时吧,一天内就通过了,微信处理挺快的呢

posted @ 2016-07-27 20:30  Danlis  阅读(1500)  评论(2编辑  收藏  举报