asp.net实现微信公众账号接口开发教程
程序员文章站
2023-12-18 13:13:28
说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方api文档。
使用.net实现的方法:
//微信...
说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方api文档。
使用.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(); }
具体处理类
/// <summary> /// 微信公众平台操作类 /// </summary> public class weixin { private string token = "my_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; //msgtype 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; //根据不同的类型进行不同的处理 switch (requestxml.msgtype) { case "text": //文本消息 requestxml.content = rootelement.selectsinglenode("content").innertext; break; case "image": //图片 requestxml.picurl = rootelement.selectsinglenode("picurl").innertext; break; case "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; break; case "link": //链接 break; case "event": //事件推送 支持v4.5+ break; } //消息回复 responsemsg(requestxml); } /// <summary> /// 验证微信签名 /// * 将token、timestamp、nonce三个参数进行字典序排序 /// * 将三个参数字符串拼接成一个字符串进行sha1加密 /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 /// </summary> /// <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"]; //加密/校验流程: //1. 将token、timestamp、nonce三个参数进行字典序排序 string[] arrtmp = { token, timestamp, nonce }; array.sort(arrtmp);//字典排序 //2.将三个参数字符串拼接成一个字符串进行sha1加密 string tmpstr = string.join("", arrtmp); tmpstr = formsauthentication.hashpasswordforstoringinconfigfile(tmpstr, "sha1"); tmpstr = tmpstr.tolower(); //3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 if (tmpstr == signature) { return true; } else { return false; } } /// <summary> /// 消息回复(微信信息返回) /// </summary> /// <param name="requestxml">the request xml.</param> private void responsemsg(requestxml requestxml) { try { string resxml = ""; //主要是调用数据库进行关键词匹配自动回复内容,可以根据自己的业务情况编写。 //1.通常有,没有匹配任何指令时,返回帮助信息 autoresponse mi = new autoresponse(requestxml.content, requestxml.fromusername); switch (requestxml.msgtype) { case "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>"; } break; case "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>"; } break; case "image": //图文混合的消息 具体格式请见官方api“回复图文消息” break; } 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(); } } /// <summary> /// 将本次交互信息保存至数据库中 /// </summary> /// <param name="requestxml"></param> /// <param name="_xml"></param> /// <param name="_pid"></param> private void writetodb(requestxml requestxml, string _xml, int _pid) { weixinmsg wx = new weixinmsg(); 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.add(); } catch (exception ex) { //wx_logs.myinsert(ex.message); //ex.message; } } }
响应类model
#region 微信请求类 requestxml /// <summary> /// 微信请求类 /// </summary> 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; } } } #endregion
本文已被整理到了《asp.net微信开发教程汇总》,欢迎大家学习阅读。
通过阅读这篇文章,大家就大概知道.net如何实现微信公众账号接口开发的,希望这篇文章对大家的学习有所帮助。