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 > 0) //有值代表创建菜单
            {
                data = encoding.GetBytes(postData);
            }

            // 准备请求...
            try
            {
                // 设置参数
                request = WebRequest.Create(posturl) as HttpWebRequest;
                CookieContainer cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                if (postData.Length > 0)
                {
                    request.Method = "POST"; //创建菜单
                }
                else
                {
                    request.Method = "GET"; //删除菜单
                }

                request.ContentType = "application/x-www-form-urlencoded";

                if (postData.Length > 0) //有值代表创建菜单
                {
                    request.ContentLength = data.Length;
                    outstream = request.GetRequestStream();
                    outstream.Write(data, 0, 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="2">
                  <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"}",说明创建成功

然后把你的微信公众号取消关注,再关注就可以看到你自己的菜单了

时间: 2024-08-02 02:48:20

C#微信公众号开发 -- (五)自定义菜单创建的相关文章

微信公众平台开发(99) 自定义菜单获取OpenID

关键字 微信公众平台 自定义菜单 OpenID作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/weixin-menu-get-openid.html 在这篇微信公众平台开发教程中,我们将介绍如何在自定义菜单中获得用户的OpenID. 本篇开发教程的实质是微信自定义菜单及OAuth2.0授权的灵活运用. 本文分为以下四个部分: 拥有高级接口权限时的获取(基于view事件) 没有高级接口权限时的获取(基于click事件) 一.拥有高级接口权限 拥有高级接口权限

微信公众平台开发(104) 自定义菜单扫一扫、发图片、发地理位置

关键字:微信公众平台 自定义菜单 扫一扫 发图片 发地理位置作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/weixin-menu-new-type.html 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的重要功能.微信增加了点击菜单后调起扫一扫(支持二维码/一维码).发图片.发地理位置的能力,需开发实现.原有自定义菜单开发权限的公众号,均可获得以上能力. 在这篇微信公众平台开发教程中,我们将介绍如何在自定义菜单上开发扫一扫.发图片.发地理

微信公众平台开发教程---自定义菜单

转载自:http://www.cnblogs.com/yank/p/3418194.html 一.概述: 如果只有输入框,可能太简单,感觉像命令行.自定义菜单,给我们提供了很大的灵活性,更符合用户的操作习惯.在一个小小的微信对话页面,可以实现更多的功能.菜单直观明了,不仅能提供事件响应,还支持URL跳转,如果需要的功能比较复杂,我们大可以使用URL跳转,跳转至我们的网页即可. 注意:自定义菜单,只有服务号才有此功能 如何注册,见第一章:微信公众账号开发教程(一) 基本原理及微信公众账号注册 效果

微信公众平台开发模式 自定义菜单 指南与菜单新建错误代码分析

简介 开发者获取使用凭证(如何获取凭证)后,可以使用该凭证对公众账号的自定义菜单进行创建.查询和删除等操作. 自定义菜单接口可实现以下类型按钮: click(点击事件): 用户点击click类型按钮后,微信服务器会通过消息接口(event类型)推送点击事件给开发者,并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值进行消息回复. 创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来.建议测试时可以尝试取消关注公众账号后,再次关注,则可以看到创建后的效果. 菜单

微信公众平台开发之自定义菜单的创建和删除

写在前: 在做这一块时,先看一下 公众平台开发文档(点击进入): 在创建菜单时,都是基于JSON传输数据,所以要用到JSON,下载相关包 点击下载: 公众平台开发文档上有说明: 请注意: 1.自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.2.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以"..."代替.3.创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来.测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果. 自定

php微信公众号开发之二级菜单

核心代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

微信公众号开发者模式自定义菜单

纯属分享 var config = require('./admin/wx/config/config'); var API = require('wechat-api'); var api = new API(config.appid, config.appsecret); api.getAccessToken(function (err, token) { console.log(err); console.log(token); //accessToken }); var menu = J

微信公众平台开发之个性菜单创建

1.先创建一个properties文件保存appid和appsecret import java.io.IOException; import java.util.Properties; //根据我创建的weixin.properties文件获取appid和appsecret public class WxConfig { private static Properties p = null; public static String getWxProperty(String key) { if

微信公众号开发中遇到的几个bug

一.测试自定义菜单接口时中文菜单名显示为null 设置的中文菜单名,中文未经过编码和解码过程,设置的中文菜单名在最后的微信服务器返回的json格式数据中显示为null. 解决办法:将中文先用unecode方法编码,最后再将菜单数组用undecode解码,再传给微信服务器.方法最上面加上header("content-type=text/html;charset=utf-8"),编码方式必须是utf-8,才能在微信公众平台在线测试接口. 二.自定义菜单中的菜单类型type="c