/// <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 = "投訴建議",});#endregionstring 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 DEBUGif (messageHandler.ResponseDocument != null){Log.Logger.Debug(messageHandler.ResponseDocument.ToString());}if (messageHandler.UsingEcryptMessage){//記錄加密后的響應信息 Log.Logger.Debug(messageHandler.FinalResponseDocument.ToString());} #endifvar 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;}}
?