本文大概介紹了使用asp.net mvc+entity framework 開發微信平台公眾號(訂閱號、服務號)的大概流程。
目錄:
- 微信公眾平台基本知識介紹
- 開發步驟
- Senparc.Weixin SDK 介紹
- 微信菜單介紹
- 微信JS SDK介紹
- 微信支付介紹
- Code First設計微信公眾平台后台實體
- BootStrap設計響應式布局介紹
一、微信公眾平台基本知識介紹
1.1請求流程
微信公眾平台是基於HTTP請求和響應
1.2 通訊格式
1.2.1消息 XML
<
xml
>
<
ToUserName
><![CDATA[gh_a96a4a619366]]></
ToUserName
>
<
FromUserName
><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></
FromUserName
>
<
CreateTime
>1357986928</
CreateTime
>
<
MsgType
><![CDATA[text]]></
MsgType
>
<
Content
><![CDATA[TNT2]]></
Content
>
<
MsgId
>5832509444155992350</
MsgId
>
</
xml
>
|
1.2.2其他接口 JSON
{ "subscribe": 1, "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", "nickname": "Band", "sex": 1, "language": "zh_CN", "city": "廣州", "province": "廣東", "country": "中國", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", "subscribe_time": 1382694957 }
1.3 可能會踩到的一些坑
- 每條XML信息都有大小限制,如文本信息,建議Content內容不要超過600字。
- 上圖中,步驟2開始之后,微信服務器有一個等待時間:5秒,如果在這個時間內沒有進行到步驟4,那么這個請求將會被關閉(包括數據傳輸的時間)。也就是說如果超過時間,即使網站服務器返回了數據,客戶端也無法收到回復。
- 在文本消息中,是允許添加<a>標簽來放置連接的,但是有許多朋友測試之后發現iOS沒問題,Android上鏈接無法點擊,其實原因是(至少目前為止):Android的微信客戶端對<a>標簽格式的判定比較嚴格,請嚴格按照這個格式書寫:<a href="http://xxxx">內容</a>,href后不要使用單引號,也不要添加其他屬性。
- 上面XML節點中的FromUserName即微信用戶的OpenId,對於同一個公眾賬號,這個OpenId的前6位是一致的,並且在整個公眾平台的記錄中也是唯一的。也就是說同一個用戶關注了兩個不同的公眾賬號,他會有兩個不同的OpenId。
- CreateTime使用的是Unix時間,因此如果使用C#的話,需要做一個轉換。
- 盡量保持官方API中XML節點的順序,以前微信服務器是使用節點位置的方式讀取信息的(node[0]),而非節點名稱,現在這個問題似乎有好轉,不過還是要小心(¥…………&%&……)。
- 由於這種特殊的通訊方式,(至少目前為止)所有請求必須從客戶端先發起,不要指望光使用API或SDK可以實現由網站服務器主動推送消息到客戶端(當然其他辦法還是有的,比如模擬登陸)。
- 微信的網頁中的Cookie是比較特殊的,僅會短暫的存在,貌似是不能設置它在很長的時間內不過期的,所以,慎用!
1.4 微信公眾平台分類
1.4.1 服務號
-
一個月可以推送4條消息
-
擁有一些高級接口(Oauth、微信支付等)
-
推送的消息如好友消息一樣單獨展示
1.4.2 訂閱號
-
每天可以推送1條消息
-
只擁有一些基本的權限
-
推送的消息在訂閱號“文件夾”中展示
1.4.3 企業號
1.4.4 開發者測試號
幾乎擁有所有權限,無支付權限,不能推送消息
1.5微信開發概況
目前市場上常見的對微信所做的開發主要分為兩部分:
1.5.1微網站
-
其實就是一個手機網站,只是很多時候需要調用微信的Oauth授權接口替代傳統的用戶登錄和注冊
-
可以調用微信JS SDK的相關功能
-
可以嵌入微信支付功能
1.5.2自動回復消息
-
用戶主動向微信公眾平台發送內容時,平台自動響應
-
獲取用戶的地理位置信息,做一些響應
-
用戶點擊菜單時的響應
-
多客服系統
二、開發步驟
三、Senparc.Weixin.MP SDK
3.1簡介
XX公司把微信官方提供的所有API都進行了封裝並開源,使開發人員可以面向對象進行微信開發,避免了請求和調試微信的接口,從而節約大量時間
官網地址:http://weixin.senparc.com/
Nuget地址:https://www.nuget.org/packages/Senparc.Weixin.MP
溫馨提醒:雖然SDK封裝好了很多的東西,但微信開發最終還是以微信的官方文檔為准,在需要時多看看微信文檔
3.2 使用SDK
- 新建ASP.NET MVC 解決方案
- 引用SDK(Nuget/項目/dll方式均可)
- 新建一個WeixinController來接收來自微信服務器的請求,新建Index Action,提供GET/POST兩種請求方式,以GET方式請求時,調用SDK的CheckSignature.Check方法,返回隨機字符串(合法性驗證),在后台配置URL時,會需要這個GET,以POST方式請求時,先調用CheckSignature.Check方法,然后定義一個MessageHandler對接收到的消息使用處理,最后返回一個MessageHandler。
public class WeiXinController : Controller { public static readonly string Token = WeixinInfo.Token;//與微信公眾賬號后台的Token設置保持一致,區分大小寫。 /// <summary> /// 微信后台驗證地址(使用Get),微信后台的“接口配置信息”的Url填寫如:http://weixin.senparc.com/weixin /// </summary> [HttpGet] [ActionName("Index")] public ActionResult Get(string signature, string timestamp, string nonce, string echostr) { if (CheckSignature.Check(signature, timestamp, nonce, Token)) { return Content(echostr); //返回隨機字符串則表示驗證通過 } else { return Content("failed:" + signature + "," + Senparc.Weixin.MP.CheckSignature.GetSignature(timestamp, nonce, Token) + "。" + "如果你在瀏覽器中看到這句話,說明此地址可以被作為微信公眾賬號后台的Url,請注意保持Token一致。"); } } /// <summary> /// 用戶發送消息后,微信平台自動Post一個請求到這里,並等待響應XML。 /// PS:此方法為簡化方法,效果與OldPost一致。 /// v0.8之后的版本可以結合Senparc.Weixin.MP.MvcExtension擴展包,使用WeixinResult,見MiniPost方法。 /// </summary> [HttpPost] [ActionName("Index")] public ActionResult Post(PostModel postModel) { if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { return Content("參數錯誤!"); } postModel.Token = Token; postModel.EncodingAESKey = WeixinInfo.EncodingAESKey;//根據自己后台的設置保持一致 postModel.AppId = WeixinInfo.AppId;//根據自己后台的設置保持一致 //v4.2.2之后的版本,可以設置每個人上下文消息儲存的最大數量,防止內存占用過多,如果該參數小於等於0,則不限制 var maxRecordCount = 10; //自定義MessageHandler,對微信請求的詳細判斷操作都在這里面。 var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount); var logger = EngineContext.Current.Resolve<DefaultLogger>(); try { /* 如果需要添加消息去重功能,只需打開OmitRepeatedMessage功能,SDK會自動處理。 * 收到重復消息通常是因為微信服務器沒有及時收到響應,會持續發送2-5條不等的相同內容的RequestMessage*/ messageHandler.OmitRepeatedMessage = false; //執行微信處理過程 messageHandler.Execute(); return new WeixinResult(messageHandler);//v0.8+ } catch (Exception ex) { logger.Error("微信請求錯誤:" + DateTime.Now.Ticks, ex); return Content(""); } } }
3.3 處理用戶發來的消息
•基本思路
重寫MessageHandler中的相應方法
public partial class CustomMessageHandler : MessageHandler<CustomMessageContext> { //some Code }
•上下文
由於是微信服務器直接發送請求到開發者服務器,故Session、Cookie均無法在微信公眾平台開發中正常使用,SDK提供了WeixinContext用來處理上下文,可以在MessageHandle中使用。
public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase> { public CustomMessageContext() { base.MessageContextRemoved += CustomMessageContext_MessageContextRemoved; } /// <summary> /// 當上下文過期,被移除時觸發的時間 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e) { /* 注意,這個事件不是實時觸發的(當然你也可以專門寫一個線程監控) * 為了提高效率,根據WeixinContext中的算法,這里的過期消息會在過期后下一條請求執行之前被清除 */ var messageContext = e.MessageContext as CustomMessageContext; if (messageContext == null) { return;//如果是正常的調用,messageContext不會為null } } }
3.4 SDK提供的常用消息事件列表
OnTextRequest |
文字消息 |
OnLocationRequest |
位置消息 |
OnVoiceRequest |
語音消息 |
OnVideoRequest |
視頻消息 |
OnImageRequest |
圖片消息 |
OnEvent_ClickRequest |
點擊菜單 |
OnEvent_SubscribeRequest |
用戶關注 |
OnEvent_UnsubscribeRequest |
取消關注 |
OnEvent_ScanRequest |
掃描二維碼 |
四、微信菜單介紹
4.1 基本介紹
- 自定義菜單分為一級菜單和二級菜單
- 一級菜單數量為1-3個,即打開公眾賬號直接可以看到排列在最下方的最多3個按鈕。一級菜單的文字最多不能超過16字節(相當於8個漢字)
- 二級菜單從屬於一級菜單,數量為1-5個。二級菜單的文字不最多不能超過40字節(相當於20個漢字)
- 當一個一級菜單下有二級菜單存在的時候,這個一級菜單按鈕被點擊不會有任何事件發生
- 可以根據后台設置的用戶分組不同,定制不同的菜單(new)
4.2菜單類型
- click:點擊推事件
- view:跳轉URL
- scancode_push:掃碼推事
- scancode_waitmsg:掃碼推事件且彈出“消息接收中”提示框
- pic_sysphoto:彈出系統拍照發圖、pic_photo_or_album:彈出拍照或者相冊發圖
- location_select:彈出地理位置選擇器
- media_id:下發消息(除文本消息)
- view_limited:跳轉圖文消息URL
五、微信JS SDK
地址:
JS地址:http://res.wx.qq.com/open/js/jweixin-1.0.0.js
文檔地址:http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html
常用功能:
-
分享接口監聽
-
圖片接口(上傳、預覽、拍照等)
-
判斷網絡狀態
-
操作右上角菜單
-
微信支付 V2
使用步驟:
- 綁定域名
先登錄微信公眾平台進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。 - 引入JS文件
在需要調用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
- 調用接口
引用后,調用相應接口就ok了。
六、微信支付介紹
6.1 簡介
微信支付分為V2 和V3 版本,V2版本嵌入在其JSSDK中,V3版本直接嵌入在微信中,無需引用任何文件。
支付方式分為JS支付和掃碼支付,我只嘗試過JS支付,並沒有嘗試掃碼支付,所以下面所說的都是JS支付(V3),掃碼支付據說是還簡單一些。JS支付最終效果跟你用微信沖話費的流程是一樣的,你可以腦海中YY一下。
測試號沒有微信支付接口,這是非常惡心的地方,你想玩玩支付?那你去注冊個公司吧~然后交點錢,注冊個服務號,再核對公司公帳,然后!@#¥#¥%此處省略一萬步~
特別需要注意的是,在開發過程中,微信的文檔是僅供參考的,他們目前對文檔管理的非常混亂,你根本不知道哪個文檔是給哪里用的,我也沒有太好的辦法,只能是多折騰吧~
6.2 准備工作
前提假設我們已經弄到了一個有支付功能的賬號,下面的
6.2.1 配置JS接口安全域名
登陸微信公眾平台后台,進入公眾號設置頁面,找到功能設置,下面有個JS接口安全域名(貌似一定要是備案過的域名才可以)
6.2.2 配置微信支付配置項
進入左側微信支付,找到開發配置,配置測試授權目錄,並把自己的微信賬號添加到測試白名單
MVC,如果支付頁面的Action是Index的話,測試授權目錄配置要配置到上一級,親測的結果是,我的支付目錄是:http://xxx.com/payment/(payment是Controller,Action是index,但是url中沒有體現)所以配置的時候,只需要配置到域名就可以了,但是要加上/,我這個最終配置的測試授權目錄是:http://xxx.com/
6.2.3 Codding
代碼要處理的流程有:
- 生成支付商品頁面
- 生成appId、timeStamp、nonceStr、package、paySign等一系列的支付簽名需要的東西,並提供給支付頁面
- JS調用微信的接口(V3)
<script language="javascript" type="text/javascript"> // 當微信內置瀏覽器完成內部初始化后會觸發WeixinJSBridgeReady事件。 function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": "@ViewData["appId"]", //公眾號名稱,由商戶傳入 "timeStamp": "@ViewData["timeStamp"]", //時間戳 "nonceStr": "@ViewData["nonceStr"]", //隨機串 "package": "@Html.Raw(ViewData["package"])",//擴展包 "signType": "MD5", //微信簽名方式:MD5 "paySign": "@ViewData["paySign"]" //微信簽名 },//josn串 function (res) { if (res.err_msg === "get_brand_wcpay_request:ok") { window.location.href = '@Url.Action("PaySuccess", new { orderNumber = Model.OrderNum })'; } } ); } function callpay() { if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } } else { jsApiCall(); } } </script>
- 接受支付成功后微信發回的確認信息,同時修改訂單狀態
這個過程細說有點復雜,下面是微信團隊提供的支付流程圖: