C#微信公众号开发 -- (五)自定义菜单建立

公众号中,底部都是有本身定义的功能按钮,经过点击某个按钮来实现指定的业务逻辑操做。html

下面就来讲说这些按钮是怎样放到微信公众平台的,仍是先来看看微信的官方解释: api

请注意: 服务器

一、自定义菜单最多包括3个一级菜单,每一个一级菜单最多包含5个二级菜单。 微信

二、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。 cookie

三、建立自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,若是发现上一次拉取菜单的请求在5分钟之前,就会拉取一下菜单, app

若是菜单有更新,就会刷新客户端的菜单。测试时能够尝试取消关注公众帐号后再次关注,则能够看到建立后的效果。 微信公众平台

自定义菜单接口可实现多种类型按钮,以下:(因为click和view是最多见的事件,因此先讲这两个) post

一、click:点击推事件 用户点击click类型按钮后,微信服务器会经过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),测试

而且带上按钮中开发者填写的key值, 开发者能够经过自定义的key值与用户进行交互;url

二、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>

这里须要注意的几点:

一、页面中我我用到了一个“建立菜单”的按钮和一个“删除菜单”的按钮,由于在建立菜单以前必需要删除以前的菜单,不然建立可能会失败(第一次的时候能够直接建立)

二、“wxAccess_token.IsExistAccess_Token(); //获取access_token”方法是我将前文提到的IsExistAccess_Token()方法和GetAccess_token()都封装到了一个wxAccess_token类中

三、建立菜单的时候请求的是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请求

四、这里我是将menu.txt和wxMenuManage.aspx放到了同一目录下,你在使用的时候注意他们的路径

这些工做完成以后,就能够在本地运行wxMenuManage.aspx页面了,

点击删除菜单按钮若是页面输出的结果是,“删除菜单结果:{"errcode":0,"errmsg":"ok"}”,说明删除成功

点击建立菜单按钮若是页面输出的结果是,“建立菜单结果:{"errcode":0,"errmsg":"ok"}",说明建立成功

而后把你的微信公众号取消关注,再关注就能够看到你本身的菜单了

相关文章
相关标签/搜索