Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明
前不久微信上线了个性化菜单接口,Senparc.Weixin SDK也已经同步更新。
本次更新升级Senparc.Weixin.MP版本到v13.5.2,依赖Senparc.Weixin版本4.5.4。.NET4.5(master) / .NET4.0两个分支都已同步更新。
由于个性化菜单变化比较大,所以对整个菜单接口进行了目前为止最大面积的重构(可以向下兼容)。
相比之前的自定义菜单,目前整个菜单相关功能针对文件结构进行了全面的整理,:
接口
菜单接口已经全部归入CommonAPIs/Menu目录下,CommonApi部分类下面再分出3个类文件:
文件名 | 说明 |
CommonApi.Menu.Common.cs | 菜单公共方法 |
CommonApi.Menu.Conditional.cs | 个性化菜单 |
CommonApi.Menu.Custom.cs | 普通自定义菜单 |
菜单接口文件
其中自定义菜单接口已经确保向下兼容,以前如果有已经开发自定义菜单功能的项目,可以放心升级。
个性化菜单类内容如下:
1 /*---------------------------------------------------------------- 2 Copyright (C) 2015 Senparc 3 4 文件名:CommonApi.Menu.Conditional 5 文件功能描述:个性化自定义菜单接口 6 7 8 创建标识:Senparc - 20151222 9 10 修改标识:Senparc - 20151222 11 修改描述:v13.5.1 添加个性化菜单接口 12 ----------------------------------------------------------------*/ 13 14 /* 15 API:http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html 16 */ 17 18 using Senparc.Weixin.Entities; 19 using Senparc.Weixin.Helpers; 20 using Senparc.Weixin.MP.Entities; 21 using Senparc.Weixin.MP.Entities.Menu; 22 23 namespace Senparc.Weixin.MP.CommonAPIs 24 { 25 public partial class CommonApi 26 { 27 /// <summary> 28 /// 创建个新华菜单 29 /// </summary> 30 /// <param name="accessTokenOrAppId">AccessToken或AppId。当为AppId时,如果AccessToken错误将自动获取一次。当为null时,获取当前注册的第一个AppId。</param> 31 /// <param name="buttonData">菜单内容</param> 32 /// <returns></returns> 33 public static CreateMenuConditionalResult CreateMenuConditional(string accessTokenOrAppId, ConditionalButtonGroup buttonData, int timeOut = Config.TIME_OUT) 34 { 35 return ApiHandlerWapper.TryCommonApi(accessToken => 36 { 37 var urlFormat = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token={0}"; 38 var jsonSetting = new JsonSetting(true); 39 return CommonJsonSend.Send<CreateMenuConditionalResult>(accessToken, urlFormat, buttonData, timeOut: timeOut, jsonSetting: jsonSetting); 40 41 }, accessTokenOrAppId); 42 } 43 44 45 #region GetMenu 46 47 /* 使用普通自定义菜单查询接口可以获取默认菜单和全部个性化菜单信息,请见自定义菜单查询接口的说明 */ 48 49 /// <summary> 50 /// 测试个性化菜单匹配结果 51 /// </summary> 52 /// <param name="accessTokenOrAppId"></param> 53 /// <param name="userId">可以是粉丝的OpenID,也可以是粉丝的微信号。</param> 54 /// <returns></returns> 55 public static MenuTryMatchResult TryMatch(string accessTokenOrAppId, string userId) 56 { 57 return ApiHandlerWapper.TryCommonApi(accessToken => 58 { 59 var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token={0}", accessToken); 60 61 var data = new 62 { 63 user_id = userId 64 }; 65 66 return CommonJsonSend.Send<MenuTryMatchResult>(accessToken, url, data, CommonJsonSendType.POST); 67 68 }, accessTokenOrAppId); 69 } 70 71 #endregion 72 73 /// <summary> 74 /// 删除菜单 75 /// </summary> 76 /// <param name="accessTokenOrAppId"></param> 77 /// <param name="menuId">菜单Id</param> 78 /// <returns></returns> 79 public static WxJsonResult DeleteMenuConditional(string accessTokenOrAppId, string menuId) 80 { 81 return ApiHandlerWapper.TryCommonApi(accessToken => 82 { 83 var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token={0}", accessToken); 84 85 var data = new 86 { 87 menuId = menuId 88 }; 89 90 return CommonJsonSend.Send(accessToken, url, data, CommonJsonSendType.POST); 91 92 }, accessTokenOrAppId); 93 94 } 95 96 /* 使用普通自定义菜单删除接口可以删除所有自定义菜单(包括默认菜单和全部个性化菜单),请见自定义菜单删除接口的说明。 */ 97 } 98 }
菜单公共方法中,GetButtonGroup()方法添加了一个参数:buttonGroup,用于指定菜单按钮列表类型(属于个性化菜单还是自定义菜单)。
实体
有关实体类的变化都体现在Entities/Menu目录下,新建了IButtonGroupBase接口以及ButtonGroupBase基类。ButtonGroup(自定义菜单)和ConditionalButtonGroup(个性化菜单)按钮都继承自ButtonGroupBase。
Entities/Menu/Buttons/目录下的所有按钮类型是通用的。
返回类型
重新整理的返回类型都在Entities/JsonResult/Menu/目录下:
注意点
- 自定义菜单和个性化菜单的菜单添加、删除接口是不同的,使用的时候需要调用各自不同的接口。
- 如果使用个性化菜单,MenuMatchRule中的规则必须至少填写一个。
- 对于使用了个性化菜单和不使用,获取菜单时返回的数据是不同的(前者包含后者),因此SDK针对这两种情况只提供了同一个实体:GetMenuResult(对应的接收消息实体为GetMenuResultFull)。有关个新华菜单的信息(列表)可以直接从GetMenuResult.conditionalmenu读取,如果为null或者列表为空,则表示没有个性化菜单。
测试和可视化编辑
源代码中提供了一个简易的可视化编辑工具,同时可以查看得到的菜单JSON数据格式(显示的是操作的实体转换成的JSON,非原始JSON)。