微信公众号开发小计(一)开发底部菜单
前期准备:(1)在微信公众平台注册账号,并申请相应的权限
(2)在基本配置中配置服务器信息,分别填写url token 并随机生成他的消息加密秘钥
注:url必须是一个完整的域名而且必须指向80或者443端口,建议使用二级域名,直接去万网解析一个就好
(3)在vs中创建项目,在本项目中叫做Travel.WeChat
项目中得实现:
(1)创建WeChatBussiness文件夹,用于存放微信的一些基础类和实体
《1》创建接受信息的基类
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Travel.WeChat.WeChatBussiness { public class ReqBaseMessage { public ReqBaseMessage() { } private string _toUserName; private string _fromUserName; private long _createTime; private string _msgType; private long _msgId; /// <summary> /// 开发者微信号 /// </summary> public string ToUserName { get { return _toUserName; } set { _toUserName = value; } } /// <summary> /// 发送者微信号 /// </summary> public string FromUserName { get { return _fromUserName; } set { _fromUserName = value; } } /// <summary> /// 消息创建时间 /// </summary> public long CreateTime { get { return _createTime; } set { _createTime = value; } } /// <summary> /// 消息类型 /// </summary> public string MsgType { get { return _msgType; } set { _msgType = value; } } /// <summary> /// 消息id,64位整型 /// </summary> public long MsgId { get { return _msgId; } set { _msgId = value; } } } }
《2》创建请求的文本类别
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Xml; namespace Travel.WeChat.WeChatBussiness { public class ReqTextMessage : ReqBaseMessage { private string _content; /// <summary> /// 消息内容 /// </summary> public string Content { get { return _content; } set { _content = value; } } public ReqTextMessage parseXml(string document) { XmlDocument xmldoc = new XmlDocument(); xmldoc.LoadXml(document); XmlElement roolelement = xmldoc.DocumentElement; ToUserName = roolelement.SelectSingleNode("ToUserName").InnerText; FromUserName = roolelement.SelectSingleNode("FromUserName").InnerText; CreateTime = Convert.ToInt64(roolelement.SelectSingleNode("CreateTime").InnerText); MsgType = roolelement.SelectSingleNode("MsgType").InnerText; MsgId = Convert.ToInt64(roolelement.SelectSingleNode("MsgId").InnerText); Content = roolelement.SelectSingleNode("Content").InnerText; return this; } } }
《3》创建响应的文本类别
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Travel.WeChat.WeChatBussiness { public class RespBaseMessage { public RespBaseMessage() { } private string _toUserName; private string _fromUserName; private long _createTime; private string _msgType; /// <summary> /// 接收方帐号 /// </summary> public string ToUserName { get { return _toUserName; } set { _toUserName = value; } } /// <summary> /// 开发者微信号 /// </summary> public string FromUserName { get { return _fromUserName; } set { _fromUserName = value; } } /// <summary> /// 消息创建时间 /// </summary> public long CreateTime { get { return _createTime; } set { _createTime = value; } } /// <summary> /// 消息类型 /// </summary> public string MsgType { get { return _msgType; } set { _msgType = value; } } } }
《4》创建响应的文本类别
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Travel.WeChat.WeChatBussiness { public class RespTextMessage : RespBaseMessage { private string _content; /// <summary> /// 消息内容 /// </summary> public string Content { get { return _content; } set { _content = value; } } public string SendContent() { return "<xml><ToUserName><![CDATA[" + ToUserName + "]]></ToUserName><FromUserName><![CDATA[" + FromUserName + "]]></FromUserName><CreateTime>" + CreateTime.ToString() + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + Content + "]]></Content></xml>"; } } }
(2)创建WeChatCode文件夹,用于存放微信的一些操作
《1》创建日志记录类
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web; namespace Travel.WeChat.WeCahtCode { public class CreateLog { /// <summary> /// 记录日志 /// </summary> /// <param name="logContext">日志内容</param> /// <param name="type">日志类型(0:错误日志;1:正常日志)</param> public static void SaveLogs(string logContext, int type) { string systemPath = "d:\\WeChatLogs"; if (type == 0) { //错误日志 try { //操作日志 string logFileName = systemPath + "\\logError_" + DateTime.Now.ToString("yyyy_MM_dd") + ".txt"; FileStream fs = new FileStream(logFileName, FileMode.Append); StreamWriter sw = new StreamWriter(fs, Encoding.Default); sw.Write("\n\r[" + DateTime.Now.ToShortTimeString() + "]\n\r\t" + logContext); sw.Close(); fs.Close(); } catch (Exception ex) { } } else if (type == 1) { try { //操作日志 string logFileName = systemPath + "\\log_" + DateTime.Now.ToString("yyyy_MM_dd") + ".txt"; FileStream fs = new FileStream(logFileName, FileMode.Append); StreamWriter sw = new StreamWriter(fs, Encoding.Default); sw.Write("\n\r[" + DateTime.Now.ToShortTimeString() + "]\n\r\t" + logContext); sw.Close(); fs.Close(); } catch (Exception ex) { } } } } }
《2》创建WeChatInit用于验证微信服务的地址
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; namespace Travel.WeChat.WeCahtCode { public class WeChatInit { /// <summary> /// 微信验证服务地址 /// </summary> /// <param name="context"></param> /// <returns></returns> public string VerificationServerUrl(HttpContext context) { string echostr = ""; string s = ""; List<string> l = new List<string>(); CreateLog.SaveLogs("1=> timestamp=" + context.Request.QueryString["timestamp"] + ";nonce=" + context.Request.QueryString["nonce"] + ";echostr=" + context.Request.QueryString["echostr"] + ";signature=" + context.Request.QueryString["signature"], 1); l.Add("微信的token"); l.Add(context.Request.QueryString["timestamp"]); l.Add(context.Request.QueryString["nonce"]); //将接收后的参数进行字典排序 list集合转化为string l.Sort(); foreach (string _s in l) s += _s; CreateLog.SaveLogs("2=>" + s, 1); //编码之后进行对比 s = FormsAuthentication.HashPasswordForStoringInConfigFile(s, "SHA1").ToLower(); if (s == context.Request.QueryString["signature"]) { CreateLog.SaveLogs("3=>OK", 1); //验证成功 返回给微信同样的数据 echostr = context.Request.QueryString["echostr"]; } else { CreateLog.SaveLogs("3=>NO", 1); } return echostr; } /// <summary> /// 当前时间字符串0 /// </summary> /// <returns></returns> public static long datetimestr() { //时间 DateTime dt = DateTime.Parse("01/01/1970 "); TimeSpan ts = DateTime.Now - dt; double sec = ts.TotalSeconds; return Convert.ToInt64(sec); } } }
《3》创建WeChatMenuManage用于创建微信的菜单
using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace Travel.WeChat.WeCahtCode { /// <summary> /// WeChatMenuManage 的摘要说明 /// </summary> public class WeChatMenuManage : IHttpHandler { public void ProcessRequest(HttpContext context) { /* wechat create menu test begin */ context.Response.ContentType = "text/plain"; //menu param string paramStr = "{\"button\": [{\"name\": \"最新产品\", \"sub_button\": [ { \"type\": \"click\",\"name\": \"最新产品\",\"key\": \"NewProduct\" }, {\"type\": \"click\", \"name\": \"最新特卖\", \"key\": \"NewSale\" }, { \"type\": \"click\", \"name\": \"当季畅销\", \"key\": \"NewSelling\" } ] }, {\"name\": \"微站\",\"sub_button\": [{\"type\": \"view\", \"name\": \"驿马微站\", \"url\": \"" + ConfigurationManager.AppSettings["wechatUrl"] + "WeChatSite/Home/Index\" } ] }, {\"name\": \"旅游攻略\", \"sub_button\": [ {\"type\": \"view\",\"name\": \"欧洲攻略\",\"url\": \"http://mp.weixin.qq.com/mp/homepage?__biz=MzI2MjQwMTE1MQ==&hid=2&sn=9da11f00955a345a391ffd319f48f574#wechat_redirect\"},{\"type\": \"view\",\"name\": \"迪拜攻略\",\"url\": \"http://mp.weixin.qq.com/mp/homepage?__biz=MzI2MjQwMTE1MQ==&hid=4&sn=6af0c8333b01edf612eda653ce1dd91d#wechat_redirect\"},{\"type\":\"view\",\"name\": \"东南亚攻略\",\"url\": \"http://mp.weixin.qq.com/mp/homepage?__biz=MzI2MjQwMTE1MQ==&hid=3&sn=0e74aa5d2025f08079c593be5bc03a36#wechat_redirect\"}]}]}"; //be post string returnStr = PostMoths("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + context.Request.QueryString["access_token"], paramStr); context.Response.Write("创建"); } public bool IsReusable { get { return false; } } public string PostMoths(string url, string param) { //创建post请求到服务器接口 string strURL = url; //创建一个请求 System.Net.HttpWebRequest request; request = (System.Net.HttpWebRequest)WebRequest.Create(strURL); //请求类型 request.Method = "POST"; //请求文本的格式编码 request.ContentType = "application/json;charset=UTF-8"; //data string paraUrlCoded = param; //字节流转化为输出流 byte[] payload; payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded); request.ContentLength = payload.Length; Stream writer = request.GetRequestStream(); //字节流写入到输出流 writer.Write(payload, 0, payload.Length); writer.Close(); //响应数据接收 流转string格式 System.Net.HttpWebResponse response; response = (System.Net.HttpWebResponse)request.GetResponse(); System.IO.Stream s; s = response.GetResponseStream(); string StrDate = ""; string strValue = ""; StreamReader Reader = new StreamReader(s, Encoding.UTF8); while ((StrDate = Reader.ReadLine()) != null) { strValue += StrDate + "\r\n"; } return strValue; } } }
《4》创建微信的入口一般处理程序 与url配置中的名称相同
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web; using Travel.WeChat.WeCahtCode; namespace Travel.WeChat { /// <summary> /// WeChatMain 的摘要说明 /// </summary> public class WeChatMain : IHttpHandler { public void ProcessRequest(HttpContext context) { string returnStr = ""; //CreateLog.SaveLogs(context.Request.HttpMethod.ToLower(), 1); //检验为get 其余为post if (context.Request.HttpMethod.ToLower() == "get") { //如果传入参数不为空 则进行验证url是否有效 if (context.Request.QueryString["signature"] != null) { WeChatInit wci = new WeChatInit(); returnStr = wci.VerificationServerUrl(context); } } else if (context.Request.HttpMethod.ToLower() == "post") { } if (returnStr != "") { context.Response.ContentType = "text/plain"; CreateLog.SaveLogs(returnStr, 1); context.Response.Write(returnStr); } } public bool IsReusable { get { return false; } } } }