欢迎使用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>☑ {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
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- Android图片下载缓存库picasso解析
- 带标签体的自定义标签
- 音频信号处理资料收集
- Activity中ConfigChanges属性的用法
- 友盟Umeng之分析统计
- 欢迎使用CSDN-markdown编辑器
- mac 安装SourceInsight
- 将html文件转换成pdf
- centos yum的使用
- 实现浏览器截图粘贴功能
- android:configChanges属性
- Android启动过程
- 写给那些仍旧在公司混日子的人
- sbt 简介 配置 加速 问题解决