微信越来越火,微信公众平台成为开发成新宠,本文用C#.net开发微信公众信号接口。
微信接口地址代码:
weixin _wx = new weixin();string postStr = "";if (Request.HttpMethod.ToLower() == "post"){Stream s = System.Web.HttpContext.Current.Request.InputStream;byte[] b = new byte[s.Length];s.Read(b, 0, (int)s.Length);postStr = Encoding.UTF8.GetString(b);if (!string.IsNullOrEmpty(postStr)) //请求处理{_wx.Handle(postStr); }}else{_wx.Auth();}微信处理类:public class weixin{private string Token = "weixin_token"; //换成自己的token public void Auth(){string echoStr = System.Web.HttpContext.Current.Request.QueryString["echoStr"];if (CheckSignature()){if (!string.IsNullOrEmpty(echoStr)){System.Web.HttpContext.Current.Response.Write(echoStr);System.Web.HttpContext.Current.Response.End();}}}public void Handle(string postStr){//封装请求类XmlDocument doc = new XmlDocument();doc.LoadXml(postStr);XmlElement rootElement = doc.DocumentElement;XmlNode MsgType = rootElement.SelectSingleNode("MsgType");RequestXML requestXML = new RequestXML();requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;requestXML.MsgType = MsgType.InnerText;if (requestXML.MsgType == "text"){requestXML.Content = rootElement.SelectSingleNode("Content").InnerText;}else if (requestXML.MsgType == "location"){requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText;requestXML.Label = rootElement.SelectSingleNode("Label").InnerText;}else if (requestXML.MsgType == "image"){requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;}//回复消息ResponseMsg(requestXML);}/// <summary>/// 验证微信签名/// </summary>/// * 将token、timestamp、nonce三个参数进行字典序排序/// * 将三个参数字符串拼接成一个字符串进行sha1加密/// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。/// <returns></returns>private bool CheckSignature(){string signature = System.Web.HttpContext.Current.Request.QueryString["signature"];string timestamp = System.Web.HttpContext.Current.Request.QueryString["timestamp"];string nonce = System.Web.HttpContext.Current.Request.QueryString["nonce"];string[] ArrTmp = { Token, timestamp, nonce };Array.Sort(ArrTmp); //字典排序string tmpStr = string.Join("", ArrTmp);tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");tmpStr = tmpStr.ToLower();if (tmpStr == signature){return true;}else{return false;}}/// <summary>/// 回复消息(微信信息返回)/// </summary>/// <param name="weixinXML"></param>private void ResponseMsg(RequestXML requestXML){try{string resxml = "";mijiya mi = new mijiya(requestXML.Content,requestXML.FromUserName);if (requestXML.MsgType == "text"){//在这里执行一系列操作,从而实现自动回复内容. string _reMsg = mi.GetReMsg();if (mi.msgType == 1){resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>2</ArticleCount><Articles>";resxml += mi.GetRePic(requestXML.FromUserName);resxml += "</Articles><FuncFlag>1</FuncFlag></xml>";}else{resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + _reMsg + "]]></Content><FuncFlag>1</FuncFlag></xml>";}}else if (requestXML.MsgType == "location"){string city = GetMapInfo(requestXML.Location_X, requestXML.Location_Y);if (city == "0"){resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[好啦,我们知道您的位置啦。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";}else{resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[好啦,我们知道您的位置啦。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";}}else if (requestXML.MsgType == "image"){resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[亲,我没有看懂你的意思。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";//返回10以内条//int size = 10;//resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>" + size + "</ArticleCount><Articles>";//List<string> list = new List<string>();////假如有20条查询的返回结果//for (int i = 0; i < 20; i++)//{//list.Add("1");//}//string[] piclist = new string[] { "/Abstract_Pencil_Scribble_Background_Vector_main.jpg", "/balloon_tree.jpg", "/bloom.jpg", "/colorful_flowers.jpg", "/colorful_summer_flower.jpg", "/fall.jpg", "/fall_tree.jpg", "/growing_flowers.jpg", "/shoes_illustration.jpg", "/splashed_tree.jpg" };//for (int i = 0; i < size && i < list.Count; i++)//{//resxml += "<item><Title><![CDATA[沈阳-黑龙江]]></Title><Description><![CDATA[元旦特价:¥300 市场价:¥400]]></Description><PicUrl><![CDATA[" + "http://www.hougelou.com" + piclist[i] + "]]></PicUrl><Url><![CDATA[http://www.hougelou.com]]></Url></item>";//}//resxml += "</Articles><FuncFlag>1</FuncFlag></xml>";}else if (wx_tmsg.GetMsgCount(requestXML.FromUserName) == 0){resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + mi.GetFirst() + "]]></Content><FuncFlag>1</FuncFlag></xml>";}else{resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[亲,我没有看懂你的意思。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";}//WriteTxt(resxml);System.Web.HttpContext.Current.Response.Write(resxml);WriteToDB(requestXML, resxml,mi.pid);}catch (Exception ex){//WriteTxt("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());wx_logs.MyInsert("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());}} /// <summary>/// unix时间转换为datetime/// </summary>/// <param name="timeStamp"></param>/// <returns></returns>private DateTime UnixTimeToTime(string timeStamp){DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));long lTime = long.Parse(timeStamp + "0000000");TimeSpan toNow = new TimeSpan(lTime);return dtStart.Add(toNow);}/// <summary>/// datetime转换为unixtime/// </summary>/// <param name="time"></param>/// <returns></returns>private int ConvertDateTimeInt(System.DateTime time){System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));return (int)(time - startTime).TotalSeconds;}/// <summary>/// 调用百度地图,返回坐标信息/// </summary>/// <param name="y">经度</param>/// <param name="x">纬度</param>/// <returns></returns>public string GetMapInfo(string x, string y){try{string res = string.Empty;string parame = string.Empty;string url = "http://maps.googleapis.com/maps/api/geocode/xml";parame = "latlng=" + x + "," + y + "&language=zh-CN&sensor=false";//此key为个人申请res = webRequestPost(url, parame);XmlDocument doc = new XmlDocument();doc.LoadXml(res);XmlElement rootElement = doc.DocumentElement;string Status = rootElement.SelectSingleNode("status").InnerText;if (Status == "OK"){//仅获取城市XmlNodeList xmlResults = rootElement.SelectSingleNode("/GeocodeResponse").ChildNodes;for (int i = 0; i < xmlResults.Count; i++){XmlNode childNode = xmlResults[i];if (childNode.Name == "status"){continue;}string city = "0";for (int w = 0; w < childNode.ChildNodes.Count; w++){for (int q = 0; q < childNode.ChildNodes[w].ChildNodes.Count; q++){XmlNode childeTwo = childNode.ChildNodes[w].ChildNodes[q];if (childeTwo.Name == "long_name"){city = childeTwo.InnerText;}else if (childeTwo.InnerText == "locality"){return city;}}}return city;}}}catch (Exception ex){//WriteTxt("map异常:" + ex.Message.ToString() + "Struck:" + ex.StackTrace.ToString());return "0";}return "0";}/// <summary>/// Post 提交调用抓取/// </summary>/// <param name="url">提交地址</param>/// <param name="param">参数</param>/// <returns>string</returns>public string webRequestPost(string url, string param){byte[] bs = System.Text.Encoding.UTF8.GetBytes(param);HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + "?" + param);req.Method = "Post";req.Timeout = 120 * 1000;req.ContentType = "application/x-www-form-urlencoded;";req.ContentLength = bs.Length;using (Stream reqStream = req.GetRequestStream()){reqStream.Write(bs, 0, bs.Length);reqStream.Flush();}using (WebResponse wr = req.GetResponse()){//在这里对接收到的页面内容进行处理 Stream strm = wr.GetResponseStream();StreamReader sr = new StreamReader(strm, System.Text.Encoding.UTF8);string line;System.Text.StringBuilder sb = new System.Text.StringBuilder();while ((line = sr.ReadLine()) != null){sb.Append(line + System.Environment.NewLine);}sr.Close();strm.Close();return sb.ToString();}}private void WriteToDB(RequestXML requestXML,string _xml,int _pid){wx_tmsg wx = new wx_tmsg();wx.AddNew();wx.FromUserName = requestXML.FromUserName;wx.ToUserName = requestXML.ToUserName;wx.MsgType = requestXML.MsgType;wx.Msg = requestXML.Content;wx.Creatime = requestXML.CreateTime;wx.Location_X = requestXML.Location_X;wx.Location_Y = requestXML.Location_Y;wx.Label = requestXML.Label;wx.Scale = requestXML.Scale;wx.PicUrl = requestXML.PicUrl;wx.reply = _xml;wx.pid = _pid;try{wx.Update();}catch (Exception ex){wx_logs.MyInsert(ex.Message);//ex.message;}}}//微信请求类public class RequestXML{private string toUserName="";/// <summary>/// 消息接收方微信号,一般为公众平台账号微信号/// </summary>public string ToUserName{get { return toUserName; }set { toUserName = value; }}private string fromUserName = "";/// <summary>/// 消息发送方微信号/// </summary>public string FromUserName{get { return fromUserName; }set { fromUserName = value; }}private string createTime = "";/// <summary>/// 创建时间/// </summary>public string CreateTime{get { return createTime; }set { createTime = value; }}private string msgType = "";/// <summary>/// 信息类型 地理位置:location,文本消息:text,消息类型:image/// </summary>public string MsgType{get { return msgType; }set { msgType = value; }}private string content = "";/// <summary>/// 信息内容/// </summary>public string Content{get { return content; }set { content = value; }}private string location_X = "";/// <summary>/// 地理位置纬度/// </summary>public string Location_X{get { return location_X; }set { location_X = value; }}private string location_Y = "";/// <summary>/// 地理位置经度/// </summary>public string Location_Y{get { return location_Y; }set { location_Y = value; }}private string scale = "";/// <summary>/// 地图缩放大小/// </summary>public string Scale{get { return scale; }set { scale = value; }}private string label = "";/// <summary>/// 地理位置信息/// </summary>public string Label{get { return label; }set { label = value; }}private string picUrl = "";/// <summary>/// 图片链接,开发者可以用HTTP GET获取/// </summary>public string PicUrl{get { return picUrl; }set { picUrl = value; }}}说明: 其中用到的mijiya类,主要是调用数据库进行关键词匹配自动回复内容,可以根据自己的业务情况编写。