前面幾篇繼續(xù)了我自己對(duì)于C#開發(fā)微信門戶及應(yīng)用的技術(shù)探索和相關(guān)的經(jīng)驗(yàn)總結(jié),繼續(xù)探索微信API并分享相關(guān)的技術(shù),一方面是為了和大家對(duì)這方面進(jìn)行互動(dòng)溝通,另一方面也是專心做好微信應(yīng)用的底層技術(shù)開發(fā),把基礎(chǔ)模塊夯實(shí),在未來的應(yīng)用中派上用途。本隨筆繼續(xù)介紹微信門戶菜單的管理操作。
1、菜單的基礎(chǔ)信息
微信門戶的菜單,一般服務(wù)號(hào)和訂閱號(hào)都可以擁有這個(gè)模塊的開發(fā),但是訂閱號(hào)好像需要認(rèn)證后才能擁有,而服務(wù)號(hào)則不需要認(rèn)證就可以擁有了。這個(gè)菜單可以有編輯模式和開發(fā)模式,編輯模式主要就是在微信門戶的平臺(tái)上,對(duì)菜單進(jìn)行編輯;而開發(fā)模式,就是用戶可以通過調(diào)用微信的API對(duì)菜單進(jìn)行定制開發(fā),通過POST數(shù)據(jù)到微信服務(wù)器,從而生成對(duì)應(yīng)的菜單內(nèi)容。本文主要介紹基于開發(fā)模式的菜單管理操作。
自定義菜單能夠幫助公眾號(hào)豐富界面,讓用戶更好更快地理解公眾號(hào)的功能。目前自定義菜單最多包括3個(gè)一級(jí)菜單,每個(gè)一級(jí)菜單最多包含5個(gè)二級(jí)菜單。一級(jí)菜單最多4個(gè)漢字,二級(jí)菜單最多7個(gè)漢字,多出來的部分將會(huì)以“...”代替。目前自定義菜單接口可實(shí)現(xiàn)兩種類型按鈕,如下:
click: 用戶點(diǎn)擊click類型按鈕后,微信服務(wù)器會(huì)通過消息接口推送消息類型為event????的結(jié)構(gòu)給開發(fā)者(參考消息接口指南),并且?guī)习粹o中開發(fā)者填寫的key值,開發(fā)者可以通過自定義的key值與用戶進(jìn)行交互; view: 用戶點(diǎn)擊view類型按鈕后,微信客戶端將會(huì)打開開發(fā)者在按鈕中填寫的url值????(即網(wǎng)頁(yè)鏈接),達(dá)到打開網(wǎng)頁(yè)的目的,建議與網(wǎng)頁(yè)授權(quán)獲取用戶基本信息接口結(jié)合,獲得用戶的登入個(gè)人信息。
菜單提交的數(shù)據(jù),本身是一個(gè)Json的數(shù)據(jù)字符串,它的官方例子數(shù)據(jù)如下所示。
?{?????"button":[ ?????{???? ??????????"type":"click",??????????"name":"今日歌曲",??????????"key":"V1001_TODAY_MUSIC" ??????}, ??????{???????????"type":"click",???????????"name":"歌手簡(jiǎn)介",???????????"key":"V1001_TODAY_SINGER" ??????}, ??????{???????????"name":"菜單",???????????"sub_button":[ ???????????{???? ???????????????"type":"view",???????????????"name":"搜索",???????????????"url":"http://www.soso.com/" ????????????}, ????????????{???????????????"type":"view",???????????????"name":"視頻",???????????????"url":"http://v.qq.com/" ????????????}, ????????????{???????????????"type":"click",???????????????"name":"贊一下我們",???????????????"key":"V1001_GOOD" ????????????}] ???????}] ?}
從上面我們可以看到,菜單不同的type類型,有不同的字段內(nèi)容,如type為view的有url屬性,而type為click的,則有key屬性。而菜單可以有子菜單sub_button屬性,總得來說,為了構(gòu)造好對(duì)應(yīng)的菜單實(shí)體類信息,不是一下就能分析的出來。
2、菜單的實(shí)體類定義
我看過一些微信接口的開發(fā)代碼,把菜單的分為了好多個(gè)實(shí)體類,指定了繼承關(guān)系,然后分別對(duì)他們進(jìn)行屬性的配置,大概的關(guān)系如下所示。
這種多層關(guān)系的繼承方式能解決問題,不過我覺得并不是優(yōu)雅的解決方案。其實(shí)結(jié)合Json.NET自身的Attribute屬性配置,可以指定那些為空的內(nèi)容在序列號(hào)為Json字符串的時(shí)候,不顯示出來的。
[JsonProperty(?NullValueHandling?=?NullValueHandling.Ignore)]
有了這個(gè)屬性,我們就可以統(tǒng)一定義菜單的實(shí)體類信息更多的屬性了,可以把View類型和Click類型的菜單屬性的url和key合并在一起。
????///?<summary> ????///?菜單基本信息????///?</summary> ????public?class?MenuInfo ????{????????///?<summary> ????????///?按鈕描述,既按鈕名字,不超過16個(gè)字節(jié),子菜單不超過40個(gè)字節(jié)????????///?</summary> ????????public?string?name?{?get;?set;?}????????///?<summary> ????????///?按鈕類型(click或view)????????///?</summary> ????????[JsonProperty(NullValueHandling?=?NullValueHandling.Ignore)]????????public?string?type?{?get;?set;?}????????///?<summary> ????????///?按鈕KEY值,用于消息接口(event類型)推送,不超過128字節(jié)????????///?</summary> ????????[JsonProperty(NullValueHandling?=?NullValueHandling.Ignore)]????????public?string?key?{?get;?set;?}????????///?<summary> ????????///?網(wǎng)頁(yè)鏈接,用戶點(diǎn)擊按鈕可打開鏈接,不超過256字節(jié)????????///?</summary> ????????[JsonProperty(NullValueHandling?=?NullValueHandling.Ignore)]????????public?string?url?{?get;?set;?}????????///?<summary> ????????///?子按鈕數(shù)組,按鈕個(gè)數(shù)應(yīng)為2~5個(gè)????????///?</summary> ????????[JsonProperty(NullValueHandling?=?NullValueHandling.Ignore)]????????public?List<MenuInfo>?sub_button?{?get;?set;?} .......
但是,這么多信息,不同的類型我需要指定不同的屬性類型,那不是挺麻煩,萬(wàn)一我在View類型的菜單里面,把key屬性設(shè)置了,那怎么辦?
解決方法就是我們定義幾個(gè)構(gòu)造函數(shù),分別用來構(gòu)造不同的菜單信息,如下所示是對(duì)菜單不同的類型,賦值給不同的屬性的構(gòu)造函數(shù)。
????????///?<summary> ????????///?參數(shù)化構(gòu)造函數(shù)????????///?</summary> ????????///?<param name="name">按鈕名稱</param> ????????///?<param name="buttonType">菜單按鈕類型</param> ????????///?<param name="value">按鈕的鍵值(Click),或者連接URL(View)</param> ????????public?MenuInfo(string?name,?ButtonType?buttonType,?string?value) ????????{????????????this.name?=?name;????????????this.type?=?buttonType.ToString();????????????if?(buttonType?==?ButtonType.click) ????????????{????????????????this.key?=?value; ????????????}????????????else?if(buttonType?==?ButtonType.view) ????????????{????????????????this.url?=?value; ????????????} ????????}
好了,還有另外一個(gè)問題,子菜單也就是屬性sub_button是可有可無的東西,有的話,需要指定Name屬性,并添加它的sub_button集合對(duì)象就可以了,那么我們?cè)谠黾右粋€(gè)構(gòu)造子菜單的對(duì)象信息的構(gòu)造函數(shù)。
????????///?<summary> ????????///?參數(shù)化構(gòu)造函數(shù),用于構(gòu)造子菜單????????///?</summary> ????????///?<param name="name">按鈕名稱</param> ????????///?<param name="sub_button">子菜單集合</param> ????????public?MenuInfo(string?name,?IEnumerable<MenuInfo>?sub_button) ????????{????????????this.name?=?name;????????????this.sub_button?=?new?List<MenuInfo>();????????????this.sub_button.AddRange(sub_button); ????????}
由于只指定Name和sub_button的屬性內(nèi)容,其他內(nèi)容為null的話,自然構(gòu)造出來的Json就沒有包含它們,非常完美!
為了獲取菜單的信息,我們還需要定義兩個(gè)實(shí)體對(duì)象,如下所示。
????///?<summary> ????///?菜單的Json字符串對(duì)象????///?</summary> ????public?class?MenuJson ????{????????public?List<MenuInfo>?button?{?get;?set;?}????????public?MenuJson() ????????{ ????????????button?=?new?List<MenuInfo>(); ????????} ????}????///?<summary> ????///?菜單列表的Json對(duì)象????///?</summary> ????public?class?MenuListJson ????{????????public?MenuJson?menu?{?get;?set;?} ????}
3、菜單管理操作的接口實(shí)現(xiàn)
我們從微信的定義里面,可以看到,我們通過API可以獲取菜單信息、創(chuàng)建菜單、刪除菜單,那么我們來定義它們的接口如下。
????///?<summary> ????///?菜單的相關(guān)操作????///?</summary> ????public?interface?IMenuApi ????{?????????????? ????????///?<summary> ????????///?獲取菜單數(shù)據(jù)????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<returns></returns> ????????MenuJson?GetMenu(string?accessToken);??????????????????????? ????????///?<summary> ????????///?創(chuàng)建菜單????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<param name="menuJson">菜單對(duì)象</param> ????????///?<returns></returns> ????????CommonResult?CreateMenu(string?accessToken,?MenuJson?menuJson);??????????????????????? ????????///?<summary> ????????///?刪除菜單????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<returns></returns> ????????CommonResult?DeleteMenu(string?accessToken); ????}
具體的獲取菜單信息的實(shí)現(xiàn)如下。
????????///?<summary> ????????///?獲取菜單數(shù)據(jù)????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<returns></returns> ????????public?MenuJson?GetMenu(string?accessToken) ????????{ ????????????MenuJson?menu?=?null;????????????var?url?=?string.Format("http://m.miracleart.cn/{0}",?accessToken); ????????????MenuListJson?list?=?JsonHelper<MenuListJson>.ConvertJson(url);????????????if?(list?!=?null) ????????????{ ????????????????menu?=?list.menu; ????????????}????????????return?menu; ????????}
這里就是把返回的Json數(shù)據(jù),統(tǒng)一轉(zhuǎn)換為我們需要的實(shí)體信息了,一步到位。
調(diào)用代碼如下所示。
????????private?void?btnGetMenuJson_Click(object?sender,?EventArgs?e) ????????{ ????????????IMenuApi?menuBLL?=?new?MenuApi(); ????????????MenuJson?menu?=?menuBLL.GetMenu(token);????????????if?(menu?!=?null) ????????????{ ????????????????Console.WriteLine(menu.ToJson()); ????????????} ????????}
創(chuàng)建和刪除菜單對(duì)象的操作實(shí)現(xiàn)如下所示。
????????///?<summary> ????????///?創(chuàng)建菜單????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<param name="menuJson">菜單對(duì)象</param> ????????///?<returns></returns> ????????public?CommonResult?CreateMenu(string?accessToken,?MenuJson?menuJson) ????????{????????????var?url?=?string.Format("http://m.miracleart.cn/{0}",?accessToken);????????????string?postData?=?menuJson.ToJson();????????????return?Helper.GetExecuteResult(url,?postData); ????????}???????????????? ????????///?<summary> ????????///?刪除菜單????????///?</summary> ????????///?<param name="accessToken">調(diào)用接口憑證</param> ????????///?<returns></returns> ????????public?CommonResult?DeleteMenu(string?accessToken) ????????{????????????var?url?=?string.Format("http://m.miracleart.cn/{0}",?accessToken);????????????return?Helper.GetExecuteResult(url); ????????}
看到這里,有些人可能會(huì)問,實(shí)體類你簡(jiǎn)化了,那么創(chuàng)建菜單是不是挺麻煩的,特別是構(gòu)造對(duì)應(yīng)的信息應(yīng)該如何操作呢?前面不是介紹了不同的構(gòu)造函數(shù)了嗎,通過他們簡(jiǎn)單就搞定了,不用記下太多的實(shí)體類及它們的繼承關(guān)系來處理菜單信息。
????????private?void?btnCreateMenu_Click(object?sender,?EventArgs?e) ????????{??????????????????????? ????????????MenuInfo?productInfo?=?new?MenuInfo("軟件產(chǎn)品",?new?MenuInfo[]?{? ????????????????new?MenuInfo("病人資料管理系統(tǒng)",?ButtonType.click,?"patient"),? ????????????????new?MenuInfo("客戶關(guān)系管理系統(tǒng)",?ButtonType.click,?"crm"),? ????????????????new?MenuInfo("酒店管理系統(tǒng)",?ButtonType.click,?"hotel"),? ????????????????new?MenuInfo("送水管理系統(tǒng)",?ButtonType.click,?"water") ????????????});???????????????????????????????????? ????????????MenuInfo?frameworkInfo?=?new?MenuInfo("框架產(chǎn)品",?new?MenuInfo[]?{? ????????????????new?MenuInfo("Win開發(fā)框架",?ButtonType.click,?"win"),????????????????new?MenuInfo("WCF開發(fā)框架",?ButtonType.click,?"wcf"),????????????????new?MenuInfo("混合式框架",?ButtonType.click,?"mix"),? ????????????????new?MenuInfo("Web開發(fā)框架",?ButtonType.click,?"web"),????????????????new?MenuInfo("代碼生成工具",?ButtonType.click,?"database2sharp") ????????????}); ????????????MenuInfo?relatedInfo?=?new?MenuInfo("相關(guān)鏈接",?new?MenuInfo[]?{? ????????????????new?MenuInfo("公司介紹",?ButtonType.click,?"Event_Company"),????????????????new?MenuInfo("官方網(wǎng)站",?ButtonType.view,?"http://m.miracleart.cn/"),????????????????new?MenuInfo("提點(diǎn)建議",?ButtonType.click,?"Event_Suggestion"),????????????????new?MenuInfo("聯(lián)系客服",?ButtonType.click,?"Event_Contact"),????????????????new?MenuInfo("發(fā)郵件",?ButtonType.view,?"http://m.miracleart.cn/") ????????????}); ????????????MenuJson?menuJson?=?new?MenuJson(); ????????????menuJson.button.AddRange(new?MenuInfo[]?{?productInfo,?frameworkInfo,?relatedInfo?});????????????//Console.WriteLine(menuJson.ToJson()); ????????????if?(MessageUtil.ShowYesNoAndWarning("您確認(rèn)要?jiǎng)?chuàng)建菜單嗎")?==?System.Windows.Forms.DialogResult.Yes) ????????????{ ????????????????IMenuApi?menuBLL?=?new?MenuApi(); ????????????????CommonResult?result?=?menuBLL.CreateMenu(token,?menuJson); ????????????????Console.WriteLine("創(chuàng)建菜單:"?+?(result.Success???"成功"?:?"失敗:"?+?result.ErrorMessage)); ????????????} ????????}
這個(gè)就是我微信門戶里面的菜單操作了,具體效果可以關(guān)注我的微信門戶:廣州愛奇迪,也可以掃描下面二維碼進(jìn)行關(guān)注了解。
菜單的效果如下:
更多C#開發(fā)微信門戶及應(yīng)用(6)--微信門戶菜單的管理操作相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)