1. 首先配置微信服務器設置html
a) 企業號配置信息 (詳見:ConfigurationManager類)算法
b) 企業號服務器配置: ConfigurationManager類json
c) 驗證響應服務器數據配置 (WeiXin類中Auth())api
企業號 基礎API 實現服務器
public class ConfigurationManager { //微信企業號iD //服務器url 驗證口令 //微信iD public static string WaiURL = "http://125.1*******4:100/"; public static string CorpToken = "個人weixin"; public static string CorpId = "wx20dfd******4e6"; public static string Srcret = "UMuGX35QgE1ra*********bPWoUHwM6OYj_vbtN7"; public static string EncodingAESKey = "oBqi7vnYgviR6sCJKqQh6Us******YIA"; ublic static string Agentid = "3"; }
public class GetAccessToken { /// <summary> /// 獲取Access_token的值 /// </summary> /// <returns></returns> public static string GetAccess_token() { //1.有沒有Token值 //if (ExistsToken() != "") //{ // return ExistsToken(); //} //2. string appid = ConfigurationManager.AppSettings["CorpId"];//從配置文件獲取Token string AppSecret = ConfigurationManager.AppSettings["Srcret"];//從配置文件獲取Token string url = String.Format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}", appid, AppSecret); string access_tokenjson = HttpRequestUtil.RequestUrl(url); LogUtil.WriteLog("原始access_tokenjson爲: " + access_tokenjson); access_tokenjson = "[" + access_tokenjson + "]"; if (access_tokenjson != "") { JArray ja = (JArray)JsonConvert.DeserializeObject(access_tokenjson); string Error = ""; try { if (access_tokenjson.Contains("errcode")) { Error = ja[0]["errcode"].ToString(); } } catch (Exception ex) { LogUtil.WriteLog("獲取access_token,未獲取到錯誤信息" + ex.Message.ToString()); } string access_token = ja[0]["access_token"].ToString(); string expires_in = ja[0]["expires_in"].ToString(); if (expires_in == "7200") { LogUtil.WriteLog("access_tokenjson 獲取成功!"); } else { LogUtil.WriteLog("access_tokenjson 獲取失敗!"); return ""; } LogUtil.WriteToken(access_token); WriteTokenTxt(access_token); return access_token; } LogUtil.WriteLog(DateTime.Now.ToString() + "access_tokenjson爲: " + access_tokenjson); return ""; } /// <summary> /// 寫入Token 和 時間校驗 值 /// </summary> /// <param name="AccessToken"></param> public static void WriteTokenTxt(string AccessToken) { //寫入Token string StartTime = DateTime.Now.ToString(); StreamWriter sw = new StreamWriter("C:\\WeiXinLog\\AccessToken.txt");//無就建立,有則覆蓋 sw.WriteLine(AccessToken); sw.Close(); //寫入Datetime StreamWriter sw1 = new StreamWriter("C:\\WeiXinLog\\AccessTokenDT.txt");//無就建立,有則覆蓋 sw1.WriteLine(DateTime.Now.ToString()); sw1.Close(); } /// <summary> /// 是否已存在Token值 /// </summary> public static string ExistsToken() { string AccessToken = ""; //讀取 try { StreamReader re = new StreamReader("C:\\WeiXinLog\\AccessToken.txt"); AccessToken = re.ReadLine(); re.Close(); if (AccessToken != "") { if (Time1() == true) { return AccessToken; } } } catch (Exception ex) { return ""; } return ""; } /// <summary> /// 是否已存在時間差值 /// </summary> public static string ExistsTokenDT() { string AccessTokenDT = ""; //讀取 try { StreamReader re = new StreamReader("C:\\WeiXinLog\\AccessTokenDT.txt"); AccessTokenDT = re.ReadLine(); re.Close(); if (AccessTokenDT != "") { return AccessTokenDT; } } catch (Exception ex) { return ""; } return ""; } //計算時間差 public static bool Time1() { //計算時間差 //DateTime startTime = Convert.ToDateTime("2015-10-19 15:43:08"); string strTime = ExistsTokenDT(); DateTime startTime = Convert.ToDateTime(strTime); DateTime endTime = Convert.ToDateTime(DateTime.Now.ToString()); TimeSpan ts = endTime - startTime; LogUtil.WriteLog("相差的總時間 用秒數表示" + ts.TotalSeconds); if (ts.TotalSeconds > 7200) { LogUtil.WriteLog(DateTime.Now.ToString() + " 時時間過時,原始時間爲:" + strTime); return false; } else { return true; } } #region /// <summary> /// 驗證Token是否過時 /// </summary> public static bool TokenExpired(string access_token) { string jsonStr = HttpRequestUtil.RequestUrl(string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", access_token)); if (jsonStr == "42001") { return true; } return false; } /// <summary> /// 建立文件夾 /// </summary> /// <param name="path"></param> /// <returns></returns> private static bool CreateFolder(string path) { if (Directory.Exists(path) == false) { //判斷文件夾是否存在 Directory.CreateDirectory(path); return true; } else { return false; } } /// <summary> /// 讀取文本Token的值 /// </summary> /// <returns></returns> public static string ReaderToken() { string myStr = ""; using (FileStream fsRead = new FileStream(@"C:\\WeiXinLog\\AccessToken.txt", FileMode.Open)) { int fsLen = (int)fsRead.Length; byte[] heByte = new byte[fsLen]; int r = fsRead.Read(heByte, 0, heByte.Length); myStr = System.Text.Encoding.UTF8.GetString(heByte); Console.WriteLine(myStr); Console.ReadKey(); } return myStr; } #endregion }
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace WeiXinProject.Como { /// <summary> /// HTTP請求工具類 /// </summary> public class HttpRequestUtil { #region 請求Url #region 請求Url,不發送數據 /// <summary> /// 請求Url,不發送數據 /// </summary> public static string RequestUrl(string url) { return RequestUrl(url, "POST"); } #endregion #region 請求Url,不發送數據 /// <summary> /// 請求Url,不發送數據 /// </summary> public static string RequestUrl(string url, string method) { // 設置參數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //發送請求並獲取相應迴應數據 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序纔開始向目標網頁發送Post請求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //返回結果網頁(html)代碼 string content = sr.ReadToEnd(); return content; } #endregion #region 請求Url,發送數據 /// <summary> /// 請求Url,發送數據 /// </summary> public static string PostUrl(string url, string postData) { byte[] data = Encoding.UTF8.GetBytes(postData); // 設置參數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; Stream outstream = request.GetRequestStream(); outstream.Write(data, 0, data.Length); outstream.Close(); //發送請求並獲取相應迴應數據 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序纔開始向目標網頁發送Post請求 Stream instream = response.GetResponseStream(); StreamReader sr = new StreamReader(instream, Encoding.UTF8); //返回結果網頁(html)代碼 string content = sr.ReadToEnd(); return content; } #endregion #endregion #region Http下載文件 /// <summary> /// Http下載文件 /// </summary> public static string HttpDownloadFile(string url, string path) { // 設置參數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //發送請求並獲取相應迴應數據 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序纔開始向目標網頁發送Post請求 Stream responseStream = response.GetResponseStream(); //建立本地文件寫入流 Stream stream = new FileStream(path, FileMode.Create); byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { stream.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } stream.Close(); responseStream.Close(); return path; } #endregion #region Http上傳文件 /// <summary> /// Http上傳文件 /// </summary> public static string HttpUploadFile(string url, string path) { // 設置參數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = "POST"; string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線 request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n"); byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); int pos = path.LastIndexOf("\\"); string fileName = path.Substring(pos + 1); //請求頭部信息 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName)); byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); byte[] bArr = new byte[fs.Length]; fs.Read(bArr, 0, bArr.Length); fs.Close(); Stream postStream = request.GetRequestStream(); postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length); postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); postStream.Write(bArr, 0, bArr.Length); postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); postStream.Close(); //發送請求並獲取相應迴應數據 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序纔開始向目標網頁發送Post請求 Stream instream = response.GetResponseStream(); StreamReader sr = new StreamReader(instream, Encoding.UTF8); //返回結果網頁(html)代碼 string content = sr.ReadToEnd(); return content; } #endregion #region 請求圖靈聊天機器人 /// <summary> /// 請求圖靈聊天機器人 /// </summary> public static string RequestTuling(string info) { info = HttpContext.Current.Server.UrlEncode(info); string url = "http://www.tuling123.com/openapi/api?key=8174df6702e9e5ab4c1396a20f5833ac&info=" + info; return RequestUrl(url, "get"); } #endregion } }
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; using System.Xml; using Tencent; namespace WeiXinProject { /// <summary> /// WeiXin 的摘要說明 /// </summary> public class WeiXin : IHttpHandler { public void ProcessRequest(HttpContext context) { string postString = string.Empty; if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST") { using (Stream stream = HttpContext.Current.Request.InputStream) { Byte[] postBytes = new Byte[stream.Length]; stream.Read(postBytes, 0, (Int32)stream.Length); postString = Encoding.UTF8.GetString(postBytes); } if (!string.IsNullOrEmpty(postString)) { // Execute(postString); postString爲:" + postString Como.LogUtil.WriteLog("========================1.WeiXin 服務器驗證========================= "); // Como.LogUtil.WriteLog("postString爲:" + postString); JMMessage(postString); } } else { Auth(); } } public bool IsReusable { get { return false; } } /// <summary> /// 成爲開發者的第一步,驗證並相應服務器的數據 /// </summary> private void Auth() { #region 獲取關鍵參數 string token = ConfigurationManager.AppSettings["CorpToken"];//從配置文件獲取Token if (string.IsNullOrEmpty(token)) { Como.LogUtil.WriteLog(string.Format("CorpToken 配置項沒有配置!")); } string encodingAESKey = ConfigurationManager.AppSettings["EncodingAESKey"];//從配置文件獲取EncodingAESKey if (string.IsNullOrEmpty(encodingAESKey)) { Como.LogUtil.WriteLog(string.Format("EncodingAESKey 配置項沒有配置!")); } string corpId = ConfigurationManager.AppSettings["CorpId"];//從配置文件獲取corpId if (string.IsNullOrEmpty(corpId)) { Como.LogUtil.WriteLog(string.Format("CorpId 配置項沒有配置!")); } #endregion string echoString = HttpContext.Current.Request.QueryString["echoStr"]; string signature = HttpContext.Current.Request.QueryString["msg_signature"];//企業號的 msg_signature string timestamp = HttpContext.Current.Request.QueryString["timestamp"]; string nonce = HttpContext.Current.Request.QueryString["nonce"]; string decryptEchoString = ""; if (new CorpBasicApi().CheckSignature(token, signature, timestamp, nonce, corpId, encodingAESKey, echoString, ref decryptEchoString)) { if (!string.IsNullOrEmpty(decryptEchoString)) { HttpContext.Current.Response.Write(decryptEchoString); HttpContext.Current.Response.End(); } } // } ///2.解密關注者消息 圖片 文字 等。。。。 public void JMMessage(string PostXML) { //公衆平臺上開發者設置的token, corpID, EncodingAESKey string sToken = ConfigurationManager.AppSettings["CorpToken"]; string sCorpID = ConfigurationManager.AppSettings["CorpId"]; string sEncodingAESKey = ConfigurationManager.AppSettings["EncodingAESKey"]; Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID); string sReqMsgSig = HttpContext.Current.Request.QueryString["msg_signature"]; string sReqTimeStamp=HttpContext.Current.Request.QueryString["timestamp"]; string sReqNonce =HttpContext.Current.Request.QueryString["nonce"]; string sReqData =PostXML; string sMsg = ""; // 解析以後的明文 int ret = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData, ref sMsg); if (ret != 0) { System.Console.WriteLine("ERR: Decrypt Fail, ret: " + ret); Como.LogUtil.WriteLog("ERR: Decrypt Fail, ret: " + ret); return; } Como.LogUtil.WriteLog("解密後:XML:" + sMsg); XmlDocument doc = new XmlDocument(); doc.LoadXml(sMsg); XmlNode root = doc.FirstChild; string MsgType = root["MsgType"].InnerText; Como.LogUtil.WriteLog("MsgType爲:" + MsgType); string FromUserName = root["FromUserName"].InnerText; Como.LogUtil.WriteLog("消息人爲:" + FromUserName); if (MsgType == "text") { string content = root["Content"].InnerText; Como.LogUtil.WriteLog("內容Content爲:" + content); SendMsg.SendMessage(FromUserName, "您好,您說的啥俺聽不懂!"); } string imgpath = "C:\\WeiXinImages\\"; string NameImg = DateTime.Now.ToString("yyyyMMDDssff") + ".JPG"; if (MsgType == "image") { Como.LogUtil.WriteLog("MsgType爲:圖片"); try { string PicUrl = root["PicUrl"].InnerText; Como.LogUtil.WriteLog("PicUrl爲:" + PicUrl); Como.Tools.DownloadPicture(PicUrl, imgpath + NameImg, -1); } catch (Exception ex) { Como.LogUtil.WriteLog("PicUrl異常爲:" + ex.Message.ToString()); } string imgpathUrl = imgpath + NameImg; SendMsg.SendMessage(FromUserName, "您好" + FromUserName + ":圖片路徑爲:" + imgpathUrl); } } } /// <summary> /// 企業號基礎操做API實現 /// </summary> public class CorpBasicApi //: ICorpBasicApi { /// <summary> /// 驗證企業號簽名 /// </summary> /// <param name="token">企業號配置的Token</param> /// <param name="signature">簽名內容</param> /// <param name="timestamp">時間戳</param> /// <param name="nonce">nonce參數</param> /// <param name="corpId">企業號ID標識</param> /// <param name="encodingAESKey">加密鍵</param> /// <param name="echostr">內容字符串</param> /// <param name="retEchostr">返回的字符串</param> /// <returns></returns> public bool CheckSignature(string token, string signature, string timestamp, string nonce, string corpId, string encodingAESKey, string echostr, ref string retEchostr) { WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpId); int result = wxcpt.VerifyURL(signature, timestamp, nonce, echostr, ref retEchostr); if (result != 0) { Como.LogUtil.WriteLog("ERR: VerifyURL fail, ret: " + result); return false; } return true; //ret==0表示驗證成功,retEchostr參數表示明文,用戶須要將retEchostr做爲get請求的返回參數,返回給企業號。 // HttpUtils.SetResponse(retEchostr); } } /// <summary> /// 回覆消息類 /// </summary> public class SendMsg { /// <summary> /// 回覆消息 /// </summary> /// <param name="UserID">回覆的指定人</param> /// <param name="StrMessg">消息內容</param> public static void SendMessage(string UserID, string StrMessg) { Como.LogUtil.WriteLog("開始回覆用戶消息,用戶:" + UserID); string Access_Token = Como.GetAccessToken.GetAccess_token(); if (Access_Token == "") Como.LogUtil.WriteException("SendMessage 未能成功加載Access_Token"); string Text = @"{ ""touser"":"; Text += '"' + UserID + '"'; Text += "," + '"' + @"msgtype"": ""text"", ""agentid"": ""3"", ""text"": { ""content"":"; Text += '"' + StrMessg + '"'; Text += @"}, ""safe"": ""0"" }"; string url = String.Format("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}", Access_Token); string strResult = Como.Tools.GetPage(url, Text); JArray ja = (JArray)JsonConvert.DeserializeObject("[" + strResult + "]"); string Error = ""; try { if (strResult.Contains("errcode")) { Error = ja[0]["errcode"].ToString(); Como.LogUtil.WriteLog(strResult); } } catch (Exception ex) { Como.LogUtil.WriteException("獲取access_token,未獲取到錯誤信息" + ex.Message.ToString()); } string errcode = ja[0]["errcode"].ToString(); string errmsg = ja[0]["errmsg"].ToString(); if (errcode == "0" && errmsg == "ok") { Como.LogUtil.WriteLog("回覆成功!"); } else { Como.LogUtil.WriteLog("回覆失敗!"); } } } }
public class SHA1UtilHelper { /// <summary> /// 簽名算法 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string GetSha1(string str) { //創建SHA1對象 SHA1 sha = new SHA1CryptoServiceProvider(); //將mystr轉換成byte[] ASCIIEncoding enc = new ASCIIEncoding(); byte[] dataToHash = enc.GetBytes(str); //Hash運算 byte[] dataHashed = sha.ComputeHash(dataToHash); //將運算結果轉換成string string hash = BitConverter.ToString(dataHashed).Replace("-", ""); return hash; } }