The previous articles continued my own technical exploration and related experience summary of C# developing WeChat portals and applications, and continued to explore WeChatAPI and share related technologies. On the one hand The purpose is to interact and communicate with everyone on this aspect. On the other hand, we are also concentrating on developing the underlying technology of WeChat applications and consolidating the basic modules so that they can be used in future applications. This essay continues to introduce the management operations of the WeChat portal menu.
WeChat portal menu, generally both service accounts and subscription accounts can have the development of this module, but the subscription account seems to need to be authenticated before it can be owned, and the service account You can have it without certification. This menu can have edit mode and development mode. The editing mode is mainly on the WeChat portal platform On the menu, edit the menu; in the development mode, users can customize and develop the menu by calling WeChat's API and POST data to the WeChat server to generate the corresponding menu content. This article mainly introduces the menu management operations based on the development mode.
Custom menu can help the official account enrich the interface, allowing users to better and faster understand the functions of the official account. Currently, the custom menu includes up to 3 first-level menus, one for each. The first-level menu contains up to 5 Second-level menu. The first-level menu can contain up to 4 Chinese characters, and the second-level menu can contain up to 7 Chinese characters. The extra parts will be replaced by "...". Interface can implement two types of buttons, as follows:
click: 用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为 event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互; view: 用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值 (即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。
The data submitted by the menu itself is a Json data character String , its official example data is as follows.
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "type":"click", "name":"歌手简介", "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" }] }] }
From the above we can see that different types of menus have different field contents, such as the type of view has url Attribute , and the type is click, there is a key attribute. The menu can have a sub-menu sub_button attribute. Generally speaking, in order to construct the corresponding menu entity class information, it cannot be analyzed at once
.I have seen some WeChat interface development codes. The menu is divided into several entity classes, specifying the inheritance relationship, and then corresponding They configure attributes, and the approximate relationship is as follows.
This multi-layer relationship inheritance method can solve the problem, but I don't think it is an elegant solution. In fact, combined with Json.NET's own Attribute attribute configuration, you can specify that those empty contents will not be displayed when the serial number is a Json string.
[JsonProperty( NullValueHandling = NullValueHandling.Ignore)]
With this attribute, we can define it uniformly. The entity class information of the menu has more attributes. You can merge the url and key of the menu attributes of the View type and Click type.
/// <summary> /// 菜单基本信息 /// </summary> public class MenuInfo { /// <summary> /// 按钮描述,既按钮名字,不超过16个字节,子菜单不超过40个字节 /// </summary> public string name { get; set; } /// <summary> /// 按钮类型(click或view) /// </summary> [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string type { get; set; } /// <summary> /// 按钮KEY值,用于消息接口(event类型)推送,不超过128字节 /// </summary> [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string key { get; set; } /// <summary> /// 网页链接,用户点击按钮可打开链接,不超过256字节 /// </summary> [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string url { get; set; } /// <summary> /// 子按钮数组,按钮个数应为2~5个 /// </summary> [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public List<MenuInfo> sub_button { get; set; } .......
However, with so much information, I need to specify different types. Attribute type, isn't that very troublesome? What if I set the key attribute in the View type menu?
The solution is that we define several constructors, They are used to construct different menu information, as shown below are the constructors that assign different attributes to different types of menus
/// <summary> /// 参数化构造函数 /// </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; } }
Okay, there is another problem, the submenu is the attribute sub_button. It is a dispensable thing. If there is one, you need to specify the Name attribute and add its sub_button collection Object. Then we are adding a constructor that constructs the object information of the submenu.
/// <summary> /// 参数化构造函数,用于构造子菜单 /// </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); }
Since only the attribute contents of Name and sub_button are specified, and if the other contents are null, the naturally constructed Json will not contain them, which is perfect!
In order to obtain menu information, we also need to define two entity objects, as shown below.
/// <summary> /// 菜单的Json字符串对象 /// </summary> public class MenuJson { public List<MenuInfo> button { get; set; } public MenuJson() { button = new List<MenuInfo>(); } } /// <summary> /// 菜单列表的Json对象 /// </summary> public class MenuListJson { public MenuJson menu { get; set; } }
From the definition of WeChat, we can see that we can obtain menu information, create menus, and delete through the API menu, then we define their interfaces as follows.
/// <summary> /// 菜单的相关操作 /// </summary> public interface IMenuApi { /// <summary> /// 获取菜单数据 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <returns></returns> MenuJson GetMenu(string accessToken); /// <summary> /// 创建菜单 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="menuJson">菜单对象</param> /// <returns></returns> CommonResult CreateMenu(string accessToken, MenuJson menuJson); /// <summary> /// 删除菜单 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <returns></returns> CommonResult DeleteMenu(string accessToken); }
The specific implementation of obtaining menu information is as follows.
/// <summary> /// 获取菜单数据 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <returns></returns> public MenuJson GetMenu(string accessToken) { MenuJson menu = null; var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken); MenuListJson list = JsonHelper<MenuListJson>.ConvertJson(url); if (list != null) { menu = list.menu; } return menu; }
这里就是把返回的Json数据,统一转换为我们需要的实体信息了,一步到位。
调用代码如下所示。
private void btnGetMenuJson_Click(object sender, EventArgs e) { IMenuApi menuBLL = new MenuApi(); MenuJson menu = menuBLL.GetMenu(token); if (menu != null) { Console.WriteLine(menu.ToJson()); } }
创建和删除菜单对象的操作实现如下所示。
/// <summary> /// 创建菜单 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="menuJson">菜单对象</param> /// <returns></returns> public CommonResult CreateMenu(string accessToken, MenuJson menuJson) { var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}", accessToken); string postData = menuJson.ToJson(); return Helper.GetExecuteResult(url, postData); } /// <summary> /// 删除菜单 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <returns></returns> public CommonResult DeleteMenu(string accessToken) { var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}", accessToken); return Helper.GetExecuteResult(url); }
看到这里,有些人可能会问,实体类你简化了,那么创建菜单是不是挺麻烦的,特别是构造对应的信息应该如何操作呢?前面不是介绍了不同的构造函数了吗,通过他们简单就搞定了,不用记下太多的实体类及它们的继承关系来处理菜单信息。
private void btnCreateMenu_Click(object sender, EventArgs e) { MenuInfo productInfo = new MenuInfo("软件产品", new MenuInfo[] { new MenuInfo("病人资料管理系统", ButtonType.click, "patient"), new MenuInfo("客户关系管理系统", ButtonType.click, "crm"), new MenuInfo("酒店管理系统", ButtonType.click, "hotel"), new MenuInfo("送水管理系统", ButtonType.click, "water") }); MenuInfo frameworkInfo = new MenuInfo("框架产品", new MenuInfo[] { new MenuInfo("Win开发框架", ButtonType.click, "win"), new MenuInfo("WCF开发框架", ButtonType.click, "wcf"), new MenuInfo("混合式框架", ButtonType.click, "mix"), new MenuInfo("Web开发框架", ButtonType.click, "web"), new MenuInfo("代码生成工具", ButtonType.click, "database2sharp") }); MenuInfo relatedInfo = new MenuInfo("相关链接", new MenuInfo[] { new MenuInfo("公司介绍", ButtonType.click, "Event_Company"), new MenuInfo("官方网站", ButtonType.view, "http://www.iqidi.com"), new MenuInfo("提点建议", ButtonType.click, "Event_Suggestion"), new MenuInfo("联系客服", ButtonType.click, "Event_Contact"), new MenuInfo("发邮件", ButtonType.view, "http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=S31yfX15fn8LOjplKCQm") }); MenuJson menuJson = new MenuJson(); menuJson.button.AddRange(new MenuInfo[] { productInfo, frameworkInfo, relatedInfo }); //Console.WriteLine(menuJson.ToJson()); if (MessageUtil.ShowYesNoAndWarning("您确认要创建菜单吗") == System.Windows.Forms.DialogResult.Yes) { IMenuApi menuBLL = new MenuApi(); CommonResult result = menuBLL.CreateMenu(token, menuJson); Console.WriteLine("创建菜单:" + (result.Success ? "成功" : "失败:" + result.ErrorMessage)); } }
菜单的效果如下:
更多C# develops WeChat portal and applies management operations of WeChat portal menu相关文章请关注PHP中文网!