欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net实现微信公众账号接口开发实例代码

程序员文章站 2024-02-28 22:11:04
说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方api文档。api文档地址:http://mp.we...

说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方api文档。
api文档地址:http://mp.weixin.qq.com/wiki/index.php

使用.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