前期准備:(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; } } } }