1. 首先配置微信服务器设置
a) 企业号配置信息 (详见:ConfigurationManager类)
b) 企业号服务器配置: ConfigurationManager类
c) 验证响应服务器数据配置 (WeiXin类中Auth())
企业号 基础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; } }