C#微信公众号开发 -- (五)自定义菜单创建
公众号中,底部都是有自己定义的功能按钮,通过点击某个按钮来实现指定的业务逻辑操作。
下面就来说说这些按钮是怎样放到微信公众平台的,还是先来看看微信的官方解释:
请注意:
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,
如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
自定义菜单接口可实现多种类型按钮,如下:(由于click和view是最常见的事件,所以先讲这两个)
1、click:点击推事件 用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),
并且带上按钮中开发者填写的key值, 开发者可以通过自定义的key值与用户进行交互;
2、view:跳转URL 用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
创建自定义菜单其实也是通过http请求方式,实现自定义菜单的写入,请求地址: https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
下面来看一下官方给出的实例:
{
"button":[
{
"type":"click",
"name":"今日歌曲",
"key":"V1001_TODAY_MUSIC"
},
{
"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"
}]
}]
}
观察上面的实例可以看出,其实就是一串JSON数据,你可以选择用字符串拼接的形式将其存储,也可以选择文件存储。
这里我使用的文件储存,将上面的实例存储到一个叫menu.txt文件中(这里建立的好处是可以把自定义菜单与微信公众号开发的程序文件分开,避免每次改自定义菜单也都要发布程序,除非有业务逻辑的更改)。建立一个专门创建自定义菜单的页面wxMenuManage.aspx,其实自定义菜单通过本地执行页面就可以将自定义菜单同步到微信服务器上面,具体请看下面的代码:
public partial class wxMenuManage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
} /// <summary>
/// 读取并创建自定义菜单
/// </summary>
private void CreateMenu()
{
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(".") + "\\menu.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("GBK"));
string menu = sr.ReadToEnd();
sr.Close();
fs.Close();
sr.Dispose();
fs.Dispose(); string access_token =wxAccess_token.IsExistAccess_Token(); //获取access_token
string i = GetPage("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token, menu);
Response.Write("创建菜单结果:" + i);
Response.End();
} /// <summary>
/// 删除菜单
/// </summary>
private void DeleteMenu()
{
string access_token =wxAccess_token.IsExistAccess_Token(); //获取access_token
string i = GetPage("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=" + access_token, "");
Response.Write("删除菜单结果:" + i);
Response.End();
} /// <summary>
/// 获取自定义菜单
/// </summary>
/// <param name="posturl">自定义菜单请求的地址</param>
/// <param name="postData">自定义菜单内容</param>
/// <returns></returns>
private string GetPage(string posturl, string postData)
{
Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
Encoding encoding = Encoding.UTF8;
byte[] data = null;
if (postData.Length > ) //有值代表创建菜单
{
data = encoding.GetBytes(postData);
} // 准备请求...
try
{
// 设置参数
request = WebRequest.Create(posturl) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
if (postData.Length > )
{
request.Method = "POST"; //创建菜单
}
else
{
request.Method = "GET"; //删除菜单
} request.ContentType = "application/x-www-form-urlencoded"; if (postData.Length > ) //有值代表创建菜单
{
request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, , data.Length);
outstream.Close();
} //发送请求并获取相应回应数据
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
string err = string.Empty;
return content;
}
catch (Exception ex)
{
string err = ex.Message;
Response.Write(err);
Response.End();
return string.Empty;
}
} /// <summary>
/// 创建菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnCreate_Click(object sender, EventArgs e)
{
CreateMenu();
} /// <summary>
/// 删除菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnDelete_Click(object sender, EventArgs e)
{
DeleteMenu();
}
}
再来看一下我的前台页面:
<form id="form1" runat="server">
<div>
<table style="width: 100%;text-align: center;margin-top: 30px;">
<tr>
<td style="text-align: right;margin-right: 10px;">
<asp:Button runat="server" ID="btnCreate" Text="创建菜单" OnClick="btnCreate_Click"/>
</td>
<td style="text-align: left;margin-left: 10px;">
<asp:Button runat="server" ID="btnDelete" Text="删除菜单" OnClick="btnDelete_Click"/>
</td>
</tr>
<tr>
<td colspan="">
<h3 style="color: red;">*注:创建之前请先删除菜单<br/>(创建完成之后新菜单将在五分钟之内生效)</h3>
</td>
</tr>
</table>
</div>
</form>
这里需要注意的几点:
1、页面中我我用到了一个“创建菜单”的按钮和一个“删除菜单”的按钮,因为在创建菜单之前必须要删除之前的菜单,否则创建可能会失败(第一次的时候可以直接创建)
2、“wxAccess_token.IsExistAccess_Token(); //获取access_token”方法是我将前文提到的IsExistAccess_Token()方法和GetAccess_token()都封装到了一个wxAccess_token类中
3、创建菜单的时候请求的是https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token使用POST请求,删除菜单的时候请求的是https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=" + access_token使用GET请求
4、这里我是将menu.txt和wxMenuManage.aspx放到了同一目录下,你在使用的时候注意他们的路径
这些工作完成之后,就可以在本地运行wxMenuManage.aspx页面了,
点击删除菜单按钮如果页面输出的结果是,“删除菜单结果:{"errcode":0,"errmsg":"ok"}”,说明删除成功
点击创建菜单按钮如果页面输出的结果是,“创建菜单结果:{"errcode":0,"errmsg":"ok"}",说明创建成功
然后把你的微信公众号取消关注,再关注就可以看到你自己的菜单了
C#微信公众号开发 -- (五)自定义菜单创建的更多相关文章
- node微信公众号开发--设置自定义菜单
var request = require("request"); const querystring = require("querystring"); re ...
- Java微信公众平台开发_04_自定义菜单
一.本节要点 1.菜单相关实体类的封装 参考官方文档中的请求包的内容,对菜单相关实体类进行封装. 2.数据传输格式—JSON 自定义菜单中请求包的数据是Json字符串格式的,请参见: Java_数据 ...
- 微信公众平台开发(99) 自定义菜单获取OpenID
关键字 微信公众平台 自定义菜单 OpenID作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/weixin-menu-get-openid.html 在这篇微信 ...
- tp6微信公众号开发者模式自定义菜单
1,参考上篇博客,获取access_token https://www.cnblogs.com/xiaoyantongxue/p/15803334.html 2:控制器写以下代码 /* * 获取普通a ...
- 微信公众号开发者模式自定义菜单 node
纯属分享 var config = require('./admin/wx/config/config'); var API = require('wechat-api'); var api = ne ...
- 微信公众号开发中遇到的几个bug
一.测试自定义菜单接口时中文菜单名显示为null 设置的中文菜单名,中文未经过编码和解码过程,设置的中文菜单名在最后的微信服务器返回的json格式数据中显示为null. 解决办法:将中文先用uneco ...
- .NET微信公众号开发-2.0创建自定义菜单
一.前言 开发之前,我们需要阅读官方的接口说明文档,不得不吐槽一下,微信的这个官方文档真的很烂,但是,为了开发我们需要的功能,我们也不得不去看这些文档. 接口文档地址:http://mp.weixin ...
- C#微信公众号开发 -- (六)自定义菜单事件之CLICK
微信公众号中当用户手动点击了按钮,微信公众号会被动的向用户发送文字消息或者图文消息. 通过C#微信公众号开发 -- (五)自定义菜单创建 我们知道了如何将CLICK类型的按钮添加到自己的微信公众平台上 ...
- .NET微信公众号开发-3.0查询自定义菜单
一.前言 前面我们已经创建好了我们的自定义菜单.那么我们现在要如何查询我们自定义的菜单.原理都是一样的,而且都是相当简单,只是接口地址文档换掉了. 2.0开始编码 同样我们首先创建好我的查询页面,在这 ...
随机推荐
- oracle的exp、imp命令
1.EXP a>完全模式 full=y EXP USER/PASSWORD@DB (AS ROLE) BUFFER=64000 FILE=C:\FULL.DMP FULL=Y b>用户模式 ...
- POJ 2240 Arbitrage spfa 判正环
d[i]代表从起点出发可以获得最多的钱数,松弛是d[v]=r*d[u],求最长路,看有没有正环 然后这题输入有毒,千万别用cin 因为是大输入,组数比较多,然后找字符串用strcmp就好,千万不要用m ...
- LightOJ 1220 Mysterious Bacteria 水题
暴力就行了,找出素因子,正的最多是30,然后负的最多是31(这一点wa了一次) #include <cstdio> #include <iostream> #include & ...
- 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。
从10G开始,Oracle提供了一个较为轻量级的客户包,叫做Instant Client. 将它安装好后,就不用再安装庞大的Oracle Client了. 这样一来,只要客户端下载Instant Cl ...
- [King.yue]关于CSLA框架的一些看法
CSLA.Net 是一个有帮助的成熟开发框架,但不适于初学者.该框架支持在任何地方.任何时间创建对象,值得我们花时间去学习了解这一框架.CSLA.Net 框架设计的业务对象,支持对完全透明的数据源进行 ...
- NPOI读取Excel案例
3.4用NPOI操作EXCEL--从Excel中抽取文本 我们知道,搜索引擎最擅长处理的就是文本,而Excel中的内容并不是以文本方式存储的.那么如果想要搜索引擎爬虫能够抓取到Excel中的内容是比较 ...
- 用opencv画矩形打上马赛克Mosaic
/*----------------------------------------------------------------------------- * * 版权声明: * 可以 ...
- 【原】Spark数据本地性
Spark数据本地性 分布式计算系统的精粹在于移动计算而非移动数据,但是在实际的计算过程中,总存在着移动数据的情况,除非是在集群的所有节点上都保存数据的副本.移动数据,将数据从一个节点移动到另一个节点 ...
- Windows下Lua+Redis 断点调试环境搭建==Linux下类似
Lua+Redis 断点调试环境搭建 windows环境,使用Redis,写lua脚本头疼的问题之一不能对脚本断点调试,google加上自己的摸索,终于搞定. 1.下载ZeroBraneStudio, ...
- LA4329 Ping pong 树状数组
题意:一条大街上住着n个乒乓球爱好者,经常组织比赛切磋技术.每个人都有一个能力值a[i].每场比赛需要三个人:两名选手,一名裁判.他们有个奇怪的约定,裁判必须住在两名选手之间,而裁判的能力值也必须在两 ...