欢迎使用CSDN-markdown编辑器

来源:互联网 发布:数据挖掘工程师面试题 编辑:程序博客网 时间:2024/05/20 13:41

asp.net 之微信自定义菜单创建

前段时间由于公司需要,申请了大批量的微信公众账号,并要求每个公众账号都需要创建自定义菜单,由于数量相当庞大,单个创建简直是个巨大的工作量,于是我开动脑筋,搞了一个自义定菜单管理后台,实现一键添加、删除自定义菜单:

  • 管理后台是基于asp.net+MVC+dwz来写,至于什么是dwz自己百度,很简单也很实用的国产开源框架
    -公众账号列表页面:
<div class="pageContent">    <div class="panelBar">        <ul class="toolBar">            <li><a class="icon" href="#" onclick="GetID()"><span>创建菜单</span></a></li>            <li><a class="delete" href="@Url.Content("~/WeiXin/DelMenu")" target="selectedTodo"  title="确定删除该账号的自定义菜单吗?">                <span>删除菜单</span></a></li>        </ul>    </div>    <table class="table" width="100%" layouth="135">        <thead>            <tr>                <th width="2%">                    <input type="checkbox" class="checkboxCtrl" group="ids" />                </th>                <th width="5%">                    序号                </th>                <th width="auto">                    区域名称                </th>                <th width="auto">                    账号                </th>                <th width="10%">                    密码                </th>                <th width="5%">                    AppID                </th>                <th width="5%">                    AppSecret                </th>                <th width="8%">                    是否认证                </th>                <th width="10%">                    是否创建菜单                </th>                <th width="8%">                    查看菜单结构                </th>                <th width="10%">                    开通时间                </th>            </tr>        </thead>        <tbody>            @{                if (dt != null)                {                    foreach (DataRow Dr in dt.Rows)                    {                <tr target="ID" rel="@Dr["ID"].ToString()">                    <td>                        @if (Convert.ToInt32(Dr["CerTification"]) == 1)                        {                            <input type="checkbox" name="ids" value="@Dr["ID"]"/>                        }                        else                        {                            <input type="checkbox" name="ids" disabled="disabled" value="-1" />                        }                    </td>                    <td align="center">@Dr["RowNumber"]                    </td>                    <td align="center">@Dr["AccountName"]                    </td>                    <td align="center">@Dr["Account"]                    </td>                    <td align="center">@Dr["PassWord"]                    </td>                    <td align="center">@Dr["AppID"]                    </td>                    <td align="center">@Dr["AppSecret"]                    </td>                    <td align="center">                        @if (Convert.ToInt32(Dr["CerTification"]) == 1)                        {                            <a class="btnSelect" title="已认证"></a>                        }                        else                        {                            <a class="btnDel" title="未认证"></a>                        }                    </td>                    <td align="center">                        @if (Convert.ToInt32(Dr["Status"]) == 2)                        {                            <a class="btnSelect" title="已创建"></a>                        }                        else                        {                            <a class="btnDel" title="未创建"></a>                        }                    </td>                    <td>                        <a class="btnLook" href="@Url.Content("~/WeiXin/FindMenu?ID=" + Dr["ID"])"  target="dialog" mask="true" width="800" height="600" title="查看菜单结构" >                        </a>                    </td>                    <td align="center">@Dr["AddTime"]                    </td>                </tr>                    }                }            }        </tbody>    </table>    <div class="panelBar">        <div class="pages">            <span>每页显示: @ViewBag.fTable.NumPerPage 条, </span><span>共 @ViewBag.fTable.RecordCount                条</span>        </div>        <div class="pagination" targetType="navTab" totalCount="@ViewBag.fTable.RecordCount" numPerPage="@ViewBag.fTable.NumPerPage" pageNumShown="10" currentPage="@ViewBag.fTable.PageNum">        </div>    </div></div>

-公众号列表为了展示所有需要创建自定义菜单的公众账号,每条数据都加了复选框,允许多个账号同时创建菜单
创建菜单按钮事件控制器:

public ActionResult CreateMenu(string s1 = "")        {            DWZJson djson = null;            if (string.IsNullOrWhiteSpace(s1))            {                djson = new DWZJson() { message = "请选择要创建菜单的公众号", statusCode = "300" };                return Content(djson.ToJsonString());            }            //string[] ids = s1.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);            //获取选中的公众账号名称            DataTable dt_accout = DALWeiXin.GetAccountList(s1);            StringBuilder sb = new StringBuilder();            if (dt_accout != null && dt_accout.Rows.Count > 0)            {                for (int i = 0; i < dt_accout.Rows.Count; i++)                {                    sb.AppendFormat("<li class='{0}' style=\"display: inline; margin-right: 10px;\"><strong>☑&nbsp;{1}</strong></li>", dt_accout.Rows[i]["ID"], HttpUtility.HtmlDecode(Convert.ToString(dt_accout.Rows[i]["AccountName"])));                }            }            ViewData["AccountList"] = sb.ToString();            //所有菜单列表            DataTable dt = DALWeiXin.getMenuList();            ViewBag.Table = dt;            ViewBag.accountID = s1;//对应公众账号id            return View();        }

选择之后弹出菜单选择窗口,菜单以树形结构分两级展示,根据直观
弹窗页面:

@using System.Data;@{    ViewBag.Title = "CreateMenu";    DataTable dt = ViewBag.Table;//菜单集合}<div class="pageContent">    <form id="Menuform" method="post" action="@Url.Content("~/WeiXin/CreateMenuSubmit")" enctype="multipart/form-data" class="pageForm required-validate"    onsubmit="return iframeCallback(this,dialogAjaxDone);">    <input type="hidden" name="ids" id="ids" value="@ViewBag.accountID" />    <div class="pageFormContent" layouth="56" style="overflow: auto;">        <div style="width: 640px; border: 1px solid rgb(204, 204, 204); line-height: 21px;            background: none repeat scroll 0% 0% rgb(255, 255, 255); height: auto;">            <ul style="margin: 15px 15px 15px; list-style: circle;">                @Html.Raw(Convert.ToString(ViewData["AccountList"]))            </ul>        </div>        <div style="float: left; display: block; overflow: auto; width: 640px; border: 1px solid rgb(204, 204, 204);            line-height: 21px; background: none repeat scroll 0% 0% rgb(255, 255, 255); height: auto;            margin-top: 20px;">            <ul class="tree treeFolder treeCheck expand">                @if (dt != null && dt.Rows.Count > 0)                {                    for (var i = 0; i < dt.Rows.Count; i++)                    {                        DataRow[] foundRow = dt.Select("PID=" + dt.Rows[i]["MID"]);                        if (Convert.ToInt32(dt.Rows[i]["PID"]) == -1 && foundRow.Length == 0)                        {                    <li><a tname="PMenu" tvalue="@dt.Rows[i]["MID"]">@dt.Rows[i]["MName"]@Html.Raw("(一级)")</a></li>                        }                        else if (Convert.ToInt32(dt.Rows[i]["PID"]) == -1 && foundRow.Length > 0)                        {                    <li><a tname="PMenu" tvalue="@dt.Rows[i]["MID"]">@dt.Rows[i]["MName"]@Html.Raw("(一级)")</a><ul>                        @for (var j = 0; j < foundRow.Length; j++)                        {                            <li><a tname="CMenu" tvalue="@foundRow[j]["MID"]">@foundRow[j]["MName"]@Html.Raw("(二级)")</a>                            </li>                        }                    </ul>                    </li>                        }                    }                }            </ul>        </div>    </div>    <div class="formBar">        <ul>            <li>                <div class="buttonActive">                    <div class="buttonContent">                        <button type="submit">                            提交</button></div>                </div>            </li>            <li>                <div class="button">                    <div class="buttonContent">                        <button type="button" class="close">                            取消</button></div>                </div>            </li>        </ul>    </div>    </form></div>

选择对应菜单之后提交事件控制器

 public ActionResult CreateMenuSubmit(FormCollection collection)        {            DWZJson djson = null;            var pmid = collection["PMenu"] == null ? "" : collection["PMenu"];//父级菜单id            var cmid = collection["CMenu"] == null ? "-1" : collection["CMenu"];//子级菜单id            var account = collection["ids"];//创建菜单所属对象(公众号)            if (string.IsNullOrWhiteSpace(pmid) &&  cmid == "-1")            {                djson = new DWZJson() { message = "请选择菜单", statusCode = "300" };                return Content(djson.ToJsonString());            }            //根据菜单编号查询所有菜单            DataTable dt = DALWeiXin.GetMenu(pmid, cmid);            if (dt != null && dt.Rows.Count > 0)            {                try                {                    //构建拼接字符串                    StringBuilder sb = new StringBuilder();                    //begin create menu                    sb.Append("{'button':[");                    for (int i = 0; i < dt.Rows.Count; i++)                    {                        DataRow[] foundRow = dt.Select("PID=" + dt.Rows[i]["MID"], "Seq DESC");                        //设置按钮类型,view: url 否则:key                        var cont = Convert.ToString(dt.Rows[i]["MType"]) == "view" ? "url" : "key";                        if (Convert.ToInt32(dt.Rows[i]["PID"]) == -1 && foundRow.Length == 0)                        {                            sb.Append("{");                            sb.AppendFormat("'name':'{0}','type':'{1}','{3}':'{2}'", dt.Rows[i]["MName"], dt.Rows[i]["MType"], dt.Rows[i]["MContent"], cont);                            sb.Append("},");                        }                        else if (Convert.ToInt32(dt.Rows[i]["PID"]) == -1 && foundRow.Length > 0)                        {                            sb.Append("{");                            sb.AppendFormat("'name':'{0}','sub_button':[", dt.Rows[i]["MName"]);                            for (int j = 0; j < foundRow.Length; j++)                            {                                cont = Convert.ToString(foundRow[j]["MType"]) == "view" ? "url" : "key";                                sb.Append("{");                                sb.AppendFormat("'name':'{0}','type':'{1}','{3}':'{2}'", foundRow[j]["MName"], foundRow[j]["MType"], foundRow[j]["MContent"], cont);                                if (j == foundRow.Length - 1)                                    sb.Append("}");                                else                                    sb.Append("},");                            }                            sb.Append("]},");                        }                    }                    sb.Append("]}");                    sb.Replace("'", "\"");                    //获取appid  appsecret 集合                    DataTable Tab = DALWeiXin.GetAccountList(account);                    if (Tab != null && Tab.Rows.Count > 0)                    {                        //消息提示,记录创建菜单返回结果                        var ShowMsg = "";                        //记录创建成功的公众账号,修改状态                        var successAccount = "";                        for (int t = 0; t < Tab.Rows.Count; t++)                        {                            //创建菜单                            string ResStr = CreateMemu(GetToken(Convert.ToString(Tab.Rows[t]["AppID"]), Convert.ToString(Tab.Rows[t]["AppSecret"])), sb.ToString());                            //解析微信后台处理之后的json字符串,提取状态值                            NameValueCollection msg = ParseJson(ResStr);                            if (msg["errcode"] == "0,")                            {                                //拼接已经创建成功的公众账号id                                successAccount += Tab.Rows[t]["ID"] + ",";                            }                            //拼接每个公众账号创建菜单的返回值                            ShowMsg += "☑" + Tab.Rows[t]["AccountName"] + ":" + msg["errmsg"];                        }                        //更改菜单创建成功的公众账号状态,记录该账号已经创建菜单 状态置为2                        bool result = DALWeiXin.UpdateAccountStatus(successAccount, 2);                        djson = new DWZJson() { message = ShowMsg, statusCode = "200" };                        return Content(djson.ToJsonString());                    }                    else                    {                        djson = new DWZJson() { message = "系统异常", statusCode = "300" };                        return Content(djson.ToJsonString());                    }                }                catch (Exception ex)                {                    djson = new DWZJson() { message = "系统异常" + ex.ToString(), statusCode = "300" };                    return Content(djson.ToJsonString());                }            }            return Content(djson.ToJsonString());        }
  /// <summary>        /// 创建自定义菜单        /// </summary>        /// <param name="weixin_token">token</param>        /// <param name="Json">json结构的菜单</param>        /// <returns></returns>        public static string CreateMemu(string weixin_token, string Json)        {            string CreateMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";//创建自定义菜单链接            string url = string.Format(CreateMenuUrl, weixin_token);            return HttpPost(url, Json); //returnData 返回的是 {"errcode":0,"errmsg":"ok"} 此时,你取消服务号关注,在添加关注,菜单就生成了         } /// <summary>          /// HTTP POST方式请求数据          /// </summary>          /// <param name="url">URL.</param>          /// <param name="param">POST的数据</param>          /// <returns></returns>          public static string HttpPost(string url, string param)        {            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);            request.Method = "POST";            request.ContentType = "application/x-www-form-urlencoded";            request.Accept = "*/*";            request.Timeout = 15000;            request.AllowAutoRedirect = false;            StreamWriter requestStream = null;            WebResponse response = null;            string responseStr = null;            try            {                requestStream = new StreamWriter(request.GetRequestStream());                requestStream.Write(param);                requestStream.Close();                response = request.GetResponse();                if (response != null)                {                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);                    responseStr = reader.ReadToEnd();                    //File.WriteAllText(Server.MapPath("~/") + @"\test.txt", responseStr);                    reader.Close();                }            }            catch (Exception)            {                throw;            }            finally            {                request = null;                requestStream = null;                response = null;            }            return responseStr;        }  /// <summary>        /// 获取access_token        /// </summary>        /// <returns></returns>        public static string GetToken(string AppID, string AppSecret)        {            string access_token = "";            string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppID + "&secret=" + AppSecret + "";//你成为开发者后会有一个appID和appSecret              string response = HttpGet(url);            JavaScriptSerializer json = new JavaScriptSerializer();   //实例化一个能够序列化数据的类              ToJson list = json.Deserialize<ToJson>(response);    //将json数据转化为对象类型并赋值给list              access_token = list.access_token;      //获取JSON里access_token值              return access_token;        }

-至于后台取数据的方法就不贴了,不同程序不同用法,以上有些代码可以删除,比喻修改状态云云,就不多说了。以上有不到位的欢迎指正。

0 0