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


        /// <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;
            }
        }
  • 相关阅读:
    Linux常用命令学习2---(文件搜索命令locate find、命令搜索命令whereis which、字符串搜索命令grep、帮助命令man)
    LeetCode Perfect Squares
    华为笔试 数字转中文拼音
    二位数组 顺时针打印矩阵
    LeetCode Interleaving String
    LeetCode Coins in a Line
    LeetCode Backpack
    LeetCode Unique Paths
    LeetCode Minimum Path Sum
    腾讯模拟笔试题
  • 原文地址:https://www.cnblogs.com/guokun/p/5843735.html
Copyright © 2020-2023  润新知