小編給大家分享一下微信公眾平臺(tái)SDK過(guò)程的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)公司長(zhǎng)期為數(shù)千家客戶(hù)提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為東營(yíng)企業(yè)提供專(zhuān)業(yè)的成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè),東營(yíng)網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。服務(wù)號(hào)說(shuō)明:給企業(yè)和組織提供更強(qiáng)大的業(yè)務(wù)服務(wù)與用戶(hù)管理能力,幫助企業(yè)快速實(shí)現(xiàn)全新的公眾號(hào)服務(wù)平臺(tái)。
.NETSDK: Loogn.WeiXinSDK (net2.0源碼,下面代碼只是大概,不太正確,請(qǐng)自行下載源碼)
由于本人用的還是NOKIA-C5,沒(méi)用過(guò)微信,對(duì)微信的了解肯定沒(méi)你多,但公司有需求,只好硬著頭皮直接看接口文檔了。
看后發(fā)現(xiàn)也挺有意思的,一個(gè)很有用的作用就是,當(dāng)用戶(hù)給公眾賬號(hào)發(fā)消息時(shí),程序可以根據(jù)用戶(hù)發(fā)的內(nèi)容自動(dòng)回復(fù)用戶(hù),比如給一個(gè)物流公司的公眾賬號(hào)發(fā)個(gè)運(yùn)單號(hào),
對(duì)方自動(dòng)回復(fù)你這個(gè)運(yùn)單號(hào)的物流詳細(xì),感覺(jué)挺酷!為了說(shuō)明方便,先給出申請(qǐng)好的公眾賬號(hào)信息:
下圖為表示上面查看物流詳細(xì)的消息流程(虛線的編號(hào)表示流程的順序):
微信會(huì)向你的URL發(fā)送兩大類(lèi)消息:
一是用戶(hù)的一般消息,如上面用戶(hù)發(fā)的運(yùn)單號(hào);
二是用戶(hù)的行為(即文檔中說(shuō)的事件) ,如用戶(hù)關(guān)注了你的公眾賬號(hào)、掃描了公眾賬號(hào)的二維碼、點(diǎn)擊了你自定義的菜單等。
你的URL就可以根據(jù)收到的消息類(lèi)型和內(nèi)容做出回應(yīng)以實(shí)現(xiàn)強(qiáng)大的業(yè)務(wù)服務(wù),如上面返回的物流詳細(xì)。消息全部是以XML格式傳遞,而SDK做的就是把XML轉(zhuǎn)換成.NET對(duì)象,以方便你編寫(xiě)業(yè)務(wù)邏輯。消息的框架類(lèi)圖表示為(點(diǎn)擊查看包括子類(lèi)的全圖):
首先有個(gè)消息基類(lèi),然后是收到的消息(RecEventBaseMsg)和回復(fù)的消息(ReplyBaseMsg),上面說(shuō)了,收到的消息分兩大類(lèi),即一般消息(RecBaseMsg)和事件消息(EventBaseMsg),收到的消息類(lèi)型用枚舉表示可以是:
其他的類(lèi)型不說(shuō),而當(dāng)MsgType為Event時(shí),消息便是EventBaseMsg的子類(lèi)了,所有EventBaseMsg的子類(lèi)的MsgType都是Event,所以EventBaseMsg類(lèi)型又有個(gè)EventType來(lái)區(qū)分不同的事件,如果你看過(guò)接口文檔,你應(yīng)該知道,它的事件類(lèi)型對(duì)我們判斷到底是哪個(gè)事件不太友好,掃描二維碼事件分了用戶(hù)已關(guān)注和未關(guān)注兩種情況,已關(guān)注時(shí)EvenType是scan,未關(guān)注時(shí)EventType是subscribe,而用戶(hù)關(guān)注事件的EventType也是subscribe,所以SDK里又加了個(gè)MyEventType:
現(xiàn)在消息的流程基本清楚了,調(diào)用SDK回復(fù)消息如下:
using System.Web;using Loogn.WeiXinSDK;using Loogn.WeiXinSDK.Message;namespace WebTest { /// <summary> /// 微信->服務(wù)器配置URL /// </summary> public class WeiXinAPI : IHttpHandler { static string Token = "Token";//這里是Token不是Access_Token public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; var signature = context.Request["signature"]; var timestamp = context.Request["timestamp"]; var nonce = context.Request["nonce"]; if (WeiXin.CheckSignature(signature, timestamp, nonce, Token))//驗(yàn)證是微信給你發(fā)的消息 { //根據(jù)注冊(cè)的消息、事件處理程序回復(fù), //如果得到?jīng)]用注冊(cè)的消息或事件,會(huì)返回ReplyEmptyMsg.Instance,即GetXML()為string.Empty,符合微信的要求 var replyMsg = WeiXin.ReplyMsg(); var xml = replyMsg.GetXML(); //WriteLog(xml); //這里可以查看回復(fù)的XML消息 context.Response.Write(xml); } else { context.Response.Write("fuck you!"); } } static WeiXinAPI() { WeiXin.ConfigGlobalCredential("appid", "appSecret"); //注冊(cè)一個(gè)消息處理程序,當(dāng)用戶(hù)發(fā)"ABC",你回復(fù)“你說(shuō):ABC”; WeiXin.RegisterMsgHandler<RecTextMsg>((msg) => { return new ReplyTextMsg { Content = "你說(shuō):" + msg.Content //FromUserName = msg.ToUserName, 默認(rèn)就是這樣,不用設(shè)置! //ToUserName = msg.FromUserName, 默認(rèn)就是這樣,不用設(shè)置! //CreateTime = DateTime.Now.Ticks 默認(rèn)就是這樣,不用設(shè)置! }; }); //注冊(cè)一個(gè)用戶(hù)關(guān)注的事件處理程序,當(dāng)用戶(hù)關(guān)注你的公眾賬號(hào)時(shí),你回復(fù)“Hello!” WeiXin.RegisterEventHandler<EventAttendMsg>((msg) => { return new ReplyTextMsg { Content = "Hello !" }; }); //還可以繼續(xù)注冊(cè)你感興趣的消息、事件處理程序 } public bool IsReusable { get { return false; } } } }
SDK包含了除(OAuth3.0網(wǎng)頁(yè)授權(quán))的所有接口的封裝,類(lèi)名及方法名都很明顯,這里就不一一演示,有興趣的朋友可以下載dll自行測(cè)試,這是一張付費(fèi)認(rèn)證過(guò)的接口圖:
接下來(lái)談?wù)剬?shí)現(xiàn)的幾個(gè)細(xì)節(jié):
一、憑據(jù)(access_token)過(guò)期
“access_token是公眾號(hào)的全局票據(jù),公眾號(hào)調(diào)用各接口時(shí)都需使用access_token。正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效。公眾號(hào)可以使用AppID和AppSecret調(diào)用本接口來(lái)獲取access_token。AppID和AppSecret可在開(kāi)發(fā)模式中獲得(需要已經(jīng)成為開(kāi)發(fā)者,且?guī)ぬ?hào)沒(méi)有異常狀態(tài))。”
根據(jù)文檔上說(shuō)的,我們可以想到用緩存(不可能每次用每次取吧!),緩存代碼是很簡(jiǎn)單的,主要是在這種情況下要能想到用緩存,下面是非完整代碼:
access_token { ; expires_in { ; Dictionary<, Credential> creds = Dictionary<, Credential> TokenUrl = Credential GetCredential( appId, = (creds.TryGetValue(appId, (cred.add_time.AddSeconds(cred.expires_in - ) <= json = Util.HttpGet2(= Util.JsonTo<Credential>
二、錯(cuò)誤碼信息
上面說(shuō)到得到憑據(jù)的代碼不完整就是因?yàn)闆](méi)有處理可能返回的錯(cuò)誤碼,微信錯(cuò)誤碼以json格式返回,如:
{"errcode":40013,"errmsg":"invalid appid"}
大部分由我們主動(dòng)調(diào)用的接口都有可能返回錯(cuò)誤碼,錯(cuò)誤碼格式與正常返回的數(shù)據(jù)格式完全不一樣,在SDK里,我是這樣處理的,先定義好錯(cuò)誤碼的模型類(lèi),我這里叫ReturnCode,是因?yàn)殄e(cuò)誤碼里還包含一個(gè){"errcode":0,"errmsg":"ok"}的請(qǐng)求成功的情況:
errcode { ; errmsg { ; + errcode + + errmsg +
定義有錯(cuò)誤碼的返回消息類(lèi)時(shí)我們就可以包含一個(gè)ReturnCode類(lèi)型的屬性了,如創(chuàng)建二維碼接口:
public class QRCodeTicket { public string ticket { get; set; } public int expire_seconds { get; set; } public ReturnCode error { get; set; } }
從返回的json到QRCodeTicket對(duì)象的代碼大概就是這樣(其他的也是類(lèi)似):
var json = Util.HttpPost2(url, data); if (json.IndexOf("ticket") > 0) { return Util.JsonTo<QRCodeTicket>(json); } else { QRCodeTicket tk = new QRCodeTicket(); tk.error = Util.JsonTo<ReturnCode>(json); return tk; }
所以用SDK調(diào)用接口后,得到的對(duì)象就可輕松判斷了:
var qrcode = WeiXin.CreateQRCode(true, 23); if (qrcode.error == null) { //返回錯(cuò)誤,可以用qrcode.error查看錯(cuò)誤消息 } else { //返回正確,可以操作qrcode.ticket }
三、反序列化
微信接口返回的json有時(shí)候?qū)ξ覀冇成涞綄?duì)象并不太直接(json格式太靈活了!),比如創(chuàng)建分組成功后返回的json:
{ "group": { "id": 107, "name": "test" } }
如果想直接用json通過(guò)反序列化得到對(duì)象,那么這個(gè)對(duì)象的類(lèi)的定義有可能會(huì)是這樣:
public class GroupInfo { public Group group { get; set; } public class Group { public int id { get; set; } public string name { get; set; } } }
訪問(wèn)的時(shí)候也會(huì)是gp.group.name,所以我說(shuō)不太直接,我們想要的類(lèi)的定義肯定是只有上面那個(gè)子類(lèi)的樣子:
public class GroupInfo { public int id { get; set; } public string name { get; set; } }
如果微信接口返回的是這樣:
{ "id": 107, "name": "test" }
就再好不過(guò)了,但人家的代碼,我們修改不了,我們只有自己想辦法.
1,要簡(jiǎn)單類(lèi),2不手動(dòng)分析json(如正則),3,不想多定義一個(gè)類(lèi),你有想到很好的方法嗎?如果有可以回復(fù)給我,而我選擇用字典來(lái)做中間轉(zhuǎn)換。
因?yàn)?strong>基本所有的json格式都可以反序列化為字典(嵌套字典,嵌套字典集合等),比如上面微信返回的json就可以用以下的類(lèi)型來(lái)表示:
Dictionary<string, Dictionary<string, object>>
json--->dict--->GroupInfo
var dict = Util.JsonTo<Dictionary<string, Dictionary<string, object>>>(json);var gi = new GroupInfo();var gpdict = dict["group"]; gi.id = Convert.ToInt32(gpdict["id"]); gi.name = gpdict["name"].ToString();
四、消息處理的優(yōu)化
"萬(wàn)物簡(jiǎn)單為美",我就是一個(gè)非常非常喜歡簡(jiǎn)單的程序員。還記得最開(kāi)始的那個(gè)消息(事件屬于消息,這里統(tǒng)稱(chēng)為消息)處理吧,我感覺(jué)是很簡(jiǎn)單的,需要處理哪個(gè)消息就注冊(cè)哪個(gè)消息的處理程序。但一開(kāi)始的時(shí)候不是這樣的,開(kāi)始的時(shí)候要手動(dòng)判斷消息類(lèi)型,就像:
using System.Web;using Loogn.WeiXinSDK;using Loogn.WeiXinSDK.Message;namespace WebTest { /// <summary> /// 微信->服務(wù)器配置URL /// </summary> public class WeiXinAPI : IHttpHandler { static string Token = "Token";//這里是Token不是Access_Token public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; var signature = context.Request["signature"]; var timestamp = context.Request["timestamp"]; var nonce = context.Request["nonce"]; if (WeiXin.CheckSignature(signature, timestamp, nonce, Token))//驗(yàn)證是微信給你發(fā)的消息 { var replyMsg = WeiXin.ReplyMsg((recEvtMsg) => { switch (recEvtMsg.MsgType) { case MsgType.text: { var msg = recEvtMsg as RecTextMsg; //這里要轉(zhuǎn)型,麻煩 return new ReplyTextMsg { Content = "你說(shuō):" + msg.Content }; } case MsgType.Event: { var evtMsg = recEvtMsg as EventBaseMsg;//這里要轉(zhuǎn)型到事件消息的基本,麻煩 switch (evtMsg.MyEventType) { case MyEventType.Attend: var msg = evtMsg as EventAttendMsg;//這個(gè)例子不需要這行代碼,但其他要用消息內(nèi)容還是要轉(zhuǎn)型,麻煩 return new ReplyTextMsg { Content = "Hello !" }; default: break; } break; } default: break; } return ReplyEmptyMsg.Instance; //嵌套switch,而且每個(gè)case都有好幾個(gè),這也不優(yōu)雅 }); var xml = replyMsg.GetXML(); //WriteLog(xml); //這里可以查看回復(fù)的XML消息 context.Response.Write(xml); } else { context.Response.Write("fuck you!"); } } public bool IsReusable { get { return false; } } } }
做優(yōu)化的時(shí)候,先是試著看能不能在MsgType和MyEventType上做文章,比如注冊(cè)時(shí)傳入MsgType和處理程序(lamba)兩個(gè)參數(shù):
public static void RegisterMsgHandler(MsgType type, Func<RecEventBaseMsg, ReplyBaseMsg> handler) { //add handler}
這樣的確是可以行的通的,但是在調(diào)用SDK注冊(cè)的時(shí)候還是要手動(dòng)轉(zhuǎn)換類(lèi)型:
WeiXin.RegisterMsgHandler(MsgType.text, (recEvtMsg) => msg = recEvtMsg ReplyTextMsg { Content = +
那么能不能每個(gè)子類(lèi)型寫(xiě)一個(gè)呢?
public static void RegisterMsgHandler(MsgType type, Func<RecTextMsg, ReplyBaseMsg> handler) { //add handler } public static void RegisterMsgHandler(MsgType type, Func<RecImageMsg, ReplyBaseMsg> handler) { //add handler } //.............
定義是可以的,來(lái)看看調(diào)用:
//可以RegisterMsgHandler(MsgType.text, new Func<RecTextMsg, ReplyBaseMsg>((msg) =>{ return new ReplyTextMsg { Content = "你說(shuō):" + msg.Content }; }));//可以RegisterMsgHandler(MsgType.text, new Func<RecImageMsg, ReplyBaseMsg>((msg) =>{ return new ReplyTextMsg { Content = "你發(fā)的圖片:" + msg.PicUrl }; }));//可以,注意這里msg的智能提示是RecTextMsg類(lèi)型RegisterMsgHandler(MsgType.text, (msg) =>{ return new ReplyTextMsg { Content = "你說(shuō):" +msg.Content}; });//可以,注意這里msg的智能提示還是RecTextMsg類(lèi)型,但用了類(lèi)型推斷,運(yùn)行時(shí)可以確定是RecImageMsg,所以可以RegisterMsgHandler(MsgType.text, (msg) =>{ return new ReplyTextMsg { Content = "你發(fā)的圖片:" + msg.PicUrl }; });//不可以,注意這里msg的智能提示還是RecTextMsg類(lèi)型,但lamba body里沒(méi)有用msg的特定子類(lèi)的屬性,類(lèi)型推斷不了,所以調(diào)用不明RegisterMsgHandler(MsgType.text, (msg) =>{ return new ReplyTextMsg { Content = "你發(fā)了個(gè)消息" }; });
從上面調(diào)用可知,想用這種方法調(diào)用,就不能隨意的用lamba表達(dá)式,我所不欲也!最后,終于用泛型搞定了
public static void RegisterMsgHandler<TMsg>(Func<TMsg, ReplyBaseMsg> handler) where TMsg : RecBaseMsg { var type = typeof(TMsg); var key = string.Empty; if (type == typeof(RecTextMsg)) { key = MsgType.text.ToString(); } else if (type == typeof(RecImageMsg)) { key = MsgType.image.ToString(); } else if (type == typeof(RecLinkMsg)) { key = MsgType.link.ToString(); } else if (type == typeof(RecLocationMsg)) { key = MsgType.location.ToString(); } else if (type == typeof(RecVideoMsg)) { key = MsgType.video.ToString(); } else if (type == typeof(RecVoiceMsg)) { key = MsgType.voice.ToString(); } else { return; } m_msgHandlers[key] = (Func<RecEventBaseMsg, ReplyBaseMsg>)handler; }
經(jīng)過(guò)這樣的變換,我們才可以像開(kāi)始那樣用簡(jiǎn)潔的lamba表達(dá)式注冊(cè)。
以上是“微信公眾平臺(tái)SDK過(guò)程的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站題目:微信公眾平臺(tái)SDK過(guò)程的示例分析-創(chuàng)新互聯(lián)
文章位置:http://vcdvsql.cn/article44/cecphe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、動(dòng)態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作、虛擬主機(jī)、網(wǎng)站維護(hù)、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容