.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