前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >asp.net web api集成微信服务(使用Senparc微信SDK)

asp.net web api集成微信服务(使用Senparc微信SDK)

作者头像
guokun
发布2020-09-03 15:40:36
1.3K0
发布2020-09-03 15:40:36
举报
文章被收录于专栏:销声匿迹销声匿迹
代码语言:javascript
复制
    /// <summary>
    /// 微信请求转发控制器
    /// </summary>
    [RoutePrefix("weixin")]
    public class WeixinController : ApiController
    {
        #region 创建微信菜单

        /// <summary>
        /// 创建微信菜单
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("menu")]
        public string CreateMenu()
        {
            #region 菜单结构构建
            ButtonGroup bg = new ButtonGroup();

            string websiteUrl = WebConfigurationManager.AppSettings["WebsiteUrl"];
            bg.button.Add(new SingleViewButton()
            {
                //url = MenuHelper.GetMenuUrl("Weixin/Index"),
                url = string.Format("{0}/{1}", websiteUrl, WebConfigurationManager.AppSettings["mainPage"]),
                name = "我要借款",
            });

            bg.button.Add(new SingleViewButton()
            {
                url = string.Format("{0}/{1}", websiteUrl, "FrontendMobile/public/view/main.html#appeal"),
                name = "投诉建议",
            });
            #endregion

            string result = string.Empty;
            try
            {
                CommonApi.CreateMenu(WeixinConfig.APPID, bg);

                result = "菜单生成成功,一般有24小时缓存时间,也可以直接取消关注再关注直接查看效果";
            }
            catch (WeixinException e)
            {
                result = e.Message;
            }

            return result;
        }

        /// <summary>
        /// 获取微信菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("menu")]
        public HttpResponseMessage GetMenu()
        {
            try
            {
                GetMenuResult result = CommonApi.GetMenu(WeixinConfig.APPID);

                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (WeixinException e)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
            }
        }

        /// <summary>
        /// 删除菜单方法
        /// </summary>
        /// <returns></returns>
        [HttpDelete]
        [Route("menu")]
        public string DeleteMenu()
        {
            try
            {
                CommonApi.DeleteMenu(WeixinConfig.APPID);

                return "删除成功,一般有24小时缓存时间,也可以直接取消关注再关注直接查看效果";
            }
            catch (WeixinException e)
            {
                return e.Message;
            }
        }

        #endregion

        #region 微信服务器消息接收及处理

        /// <summary>
        /// 微信后台验证地址(使用Get),微信后台的“接口配置信息”的Url填写如:http://weixin.senparc.com/weixin
        /// </summary>
        [HttpGet]
        [Route("")]
        public HttpResponseMessage Get(string signature, string timestamp, string nonce, string echostr)
        {
            if (CheckSignature.Check(signature, timestamp, nonce, WeixinConfig.TOKEN))
            {
                var result = new StringContent(echostr, UTF8Encoding.UTF8, "application/x-www-form-urlencoded");
                var response = new HttpResponseMessage { Content = result };
                return response;
            }

            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, WeixinConfig.TOKEN) + "。" +
                    "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。");
        }

        /// <summary>
        /// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。
        /// PS:此方法为简化方法,效果与OldPost一致。
        /// v0.8之后的版本可以结合Senparc.Weixin.MP.MvcExtension扩展包,使用WeixinResult,见MiniPost方法。
        /// </summary>
        [HttpPost]
        [Route("")]
        public HttpResponseMessage Post()
        {
            var requestQueryPairs = Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value);
            if (requestQueryPairs.Count == 0
                || !requestQueryPairs.ContainsKey("timestamp")
                || !requestQueryPairs.ContainsKey("signature")
                || !requestQueryPairs.ContainsKey("nonce")
                || !CheckSignature.Check(requestQueryPairs["signature"], requestQueryPairs["timestamp"], 
                    requestQueryPairs["nonce"], WeixinConfig.TOKEN))
            {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "未授权请求");
            }
            PostModel postModel = new PostModel
            {
                Signature = requestQueryPairs["signature"],
                Timestamp = requestQueryPairs["timestamp"],
                Nonce = requestQueryPairs["nonce"]
            };
            postModel.Token = WeixinConfig.TOKEN;
            postModel.EncodingAESKey = WeixinConfig.ENCODINGAESKEY;//根据自己后台的设置保持一致
            postModel.AppId = WeixinConfig.APPID;//根据自己后台的设置保持一致

            //v4.2.2之后的版本,可以设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制
            var maxRecordCount = 10;

            //自定义MessageHandler,对微信请求的详细判断操作都在这里面。
            var messageHandler = new CusMessageHandler(Request.Content.ReadAsStreamAsync().Result, postModel, maxRecordCount);

            try
            {
#if DEBUG             
                Log.Logger.Debug(messageHandler.RequestDocument.ToString());
                if (messageHandler.UsingEcryptMessage)
                {
                    Log.Logger.Debug(messageHandler.EcryptRequestDocument.ToString());
                }
#endif
                /* 如果需要添加消息去重功能,只需打开OmitRepeatedMessage功能,SDK会自动处理。
                 * 收到重复消息通常是因为微信服务器没有及时收到响应,会持续发送2-5条不等的相同内容的RequestMessage*/
                messageHandler.OmitRepeatedMessage = true;

                //执行微信处理过程
                messageHandler.Execute();

#if DEBUG
                if (messageHandler.ResponseDocument != null)
                {
                    Log.Logger.Debug(messageHandler.ResponseDocument.ToString());
                }

                if (messageHandler.UsingEcryptMessage)
                {
                    //记录加密后的响应信息
                    Log.Logger.Debug(messageHandler.FinalResponseDocument.ToString());
                }
#endif

                var resMessage = Request.CreateResponse(HttpStatusCode.OK); 
                resMessage.Content = new StringContent(messageHandler.ResponseDocument.ToString());
                resMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");            

                return resMessage;
            }
            catch (Exception ex)
            {
                Log.Logger.Error("处理微信请求出错:", ex);
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "处理微信请求出错");
            }
        }

        #endregion

        #region JSSDK相关

        /// <summary>
        /// 获取JSSDK参数信息
        /// </summary>
        /// <param name="url">获取签名所用的URL</param>
        /// <returns></returns>
        [HttpGet]
        [Route("JSSDK/{*url}")]
        public HttpResponseMessage GetJSSDK(string url)
        {
            if (!HttpContext.Current.SideInWeixinBroswer())
            {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "请通过微信端登录");
            }

            try
            {
                //获取时间戳
                var timestamp = JSSDKHelper.GetTimestamp();
                //获取随机码
                var nonceStr = JSSDKHelper.GetNoncestr();
                string ticket = AccessTokenContainer.TryGetJsApiTicket(WeixinConfig.APPID, WeixinConfig.APPSECRET);
                //获取签名
                var signature = JSSDKHelper.GetSignature(ticket, nonceStr, timestamp, HttpUtility.UrlDecode(url));

                return Request.CreateResponse(HttpStatusCode.OK, new
                    {
                        appId = WeixinConfig.APPID,
                        timestamp = timestamp,
                        nonceStr = nonceStr,
                        signature = signature
                    });
            }
            catch (Exception e)
            {
                Log.Logger.Error("获取JSSDK信息出错:", e);

                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "获取JSSDK信息出错");
            }
        }

        #endregion

        /// <summary>
        /// 微信菜单导航
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("index")]
        public HttpResponseMessage Index(string code, string state)
        {
            var response = Request.CreateResponse(HttpStatusCode.Redirect);
            try
            {
                var result = OAuthApi.GetAccessToken(WeixinConfig.APPID, WeixinConfig.APPSECRET, code);                
                response.Headers.Location = new Uri(string.Format("{0}?openId={1}", WebConfigurationManager.AppSettings["mainPage"], result.openid), UriKind.Relative);
            }
            catch (WeixinException e)
            {
                Log.Logger.Error("OAuth2授权失败:", e);
                response.Headers.Location = new Uri(WebConfigurationManager.AppSettings["mainPage"], UriKind.Relative);
            }

            return response;
        }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-09-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档