当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net微信开发(消息应答)

asp.net微信开发(消息应答)

2017年12月12日  | 移动技术网IT编程  | 我要评论

冒险岛大丽花,母娘来了,欢乐谷特洛伊木马

当普通微信用户向公众账号发消息时,微信服务器将post消息的xml数据包到开发者填写的url上。
请注意:

  • 1、关于重试的消息排重,推荐使用msgid排重。
  • 2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。
  • 3、为了保证更高的安全保障,开发者可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息会被加密,公众号被动回复用户的消息也需要加密(但开发者通过客服接口等api调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“消息加解密说明”。

各消息类型的推送xml数据包结构如下:
文本消息

 <xml>
 <tousername><![cdata[touser]]></tousername>
 <fromusername><![cdata[fromuser]]></fromusername> 
 <createtime>1348831860</createtime>
 <msgtype><![cdata[text]]></msgtype>
 <content><![cdata[this is a test]]></content>
 <msgid>1234567890123456</msgid>
 </xml>

  图片消息 

<xml>
 <tousername><![cdata[touser]]></tousername>
 <fromusername><![cdata[fromuser]]></fromusername>
 <createtime>1348831860</createtime>
 <msgtype><![cdata[image]]></msgtype>
 <picurl><![cdata[this is a url]]></picurl>
 <mediaid><![cdata[media_id]]></mediaid>
 <msgid>1234567890123456</msgid>
 </xml>

 

语音消息

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1357290913</createtime>
<msgtype><![cdata[voice]]></msgtype>
<mediaid><![cdata[media_id]]></mediaid>
<format><![cdata[format]]></format>
<msgid>1234567890123456</msgid>
</xml>

 请注意,开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息xml数据包中,增加一个recongnition字段 (注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效。开发者可以重新关注此帐号进行测试)。开启语音识别后的语音xml数据包如下:

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1357290913</createtime>
<msgtype><![cdata[voice]]></msgtype>
<mediaid><![cdata[media_id]]></mediaid>
<format><![cdata[format]]></format>
<recognition><![cdata[腾讯微信团队]]></recognition>
<msgid>1234567890123456</msgid>
</xml>

多出的字段中,format为语音格式,一般为amr,recognition为语音识别结果,使用utf8编码。
视频消息

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1357290913</createtime>
<msgtype><![cdata[video]]></msgtype>
<mediaid><![cdata[media_id]]></mediaid>
<thumbmediaid><![cdata[thumb_media_id]]></thumbmediaid>
<msgid>1234567890123456</msgid>
</xml>

 

小视频消息

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1357290913</createtime>
<msgtype><![cdata[shortvideo]]></msgtype>
<mediaid><![cdata[media_id]]></mediaid>
<thumbmediaid><![cdata[thumb_media_id]]></thumbmediaid>
<msgid>1234567890123456</msgid>
</xml>

 地理位置消息

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1351776360</createtime>
<msgtype><![cdata[location]]></msgtype>
<location_x>23.134521</location_x>
<location_y>113.358803</location_y>
<scale>20</scale>
<label><![cdata[位置信息]]></label>
<msgid>1234567890123456</msgid>
</xml> 

 

链接消息

<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime>1351776360</createtime>
<msgtype><![cdata[link]]></msgtype>
<title><![cdata[公众平台官网链接]]></title>
<description><![cdata[公众平台官网链接]]></description>
<url><![cdata[url]]></url>
<msgid>1234567890123456</msgid>
</xml> 

 

接上篇,看responsexml(poststring);方法如下

 /// <summary>
 /// 获取用户发送的消息
 /// </summary>
 /// <param name="poststring"></param>
 private void responsexml(string poststring)
 {
 //使用xmldocument加载信息结构  
 xmldocument xmldoc = new xmldocument();
 xmldoc.loadxml(poststring);

 xmlelement rootelement = xmldoc.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;

 }
 if (requestxml.msgtype.trim() == "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;
 }
 if (requestxml.msgtype.trim().tolower() == "event")
 {
 ///赋值事件名称和事件key值
 requestxml.eventname = rootelement.selectsinglenode("event").innertext;
 requestxml.eventkey = rootelement.selectsinglenode("eventkey").innertext;

 }

      if (requestxml.msgtype.trim().tolower() == "voice")
 {
 ///赋值语音识别结果,赋值之前一定要记得在开发者模式下,把语音识别功能开启,否则获取不到
 requestxml.recognition = rootelement.selectsinglenode("recognition").innertext;

 }
 responsemsg(requestxml);

}

语音识别功能开启如下:

 

requestxml是我单独创建的一个类,该类声明了消息中常用的属性字段,如下:

 /// <summary>
 /// 接收消息的实体类
 /// </summary>
 public class requestxml
 {
 private string tousername = string.empty;

 /// <summary>
 /// 本公众号
 /// </summary>
 public string tousername{get;set;}

 /// <summary>
 /// 用户微信号
 /// </summary>
 public string fromusername{get;set;}

 /// <summary>
 /// 创建时间
 /// </summary>
 public string createtime{get;set;}

 /// <summary>
 /// 信息类型 
 /// </summary>
 public string msgtype{get;set;}

 /// <summary>
 /// 信息内容
 /// </summary>
 public string content{get;set;}

 

 /*以下为事件类型的消息特有的属性*/
 /// <summary>
 /// 事件名称
 /// </summary>
 public string eventname{get;set;}
 /// <summary>
 /// 事件值
 /// </summary>
 public string eventkey { get; set; }

 


 /*以下为图文类型的消息特有的属性*/
 /// <summary>
 /// 图文消息的个数
 /// </summary>
 public int articlecount { get; set; }
 /// <summary>
 /// 图文消息的标题
 /// </summary>
 public string title { get; set; }
 /// <summary>
 /// 图文消息的简介
 /// </summary>
 public string description { get; set; }
 /// <summary>
 /// 图文消息图片的链接地址
 /// </summary>
 public string picurl { get; set; }
 /// <summary>
 /// 图文消息详情链接地址
 /// </summary>
 public string url { get; set; }
 /// <summary>
 /// 图文消息集合
 /// </summary>
 public list<requestxml> articles { get; set;}

 

 /*以下为地理位置类型的消息特有的属性*/
 /// <summary>
 /// 地理位置纬度
 /// </summary>
 public string location_x { get; set; }

 /// <summary>
 /// 地理位置经度
 /// </summary>
 public string location_y { get; set; }

 /// <summary>
 /// 地图缩放比例
 /// </summary>
 public string scale { get; set; }

 /// <summary>
 /// 地图位置说明
 /// </summary>
 public string label { get; set; }

   /// <summary>
 /// 语音消息特有字段
 /// </summary>
 public string recognition { get; set; }


 
 }

继续关注  responsemsg(requestxml);方法如下

 private void responsemsg(requestxml requestxml)
 {
 string msgtype = requestxml.msgtype;

 try
 {
 //根据消息类型判断发送何种类型消息
 switch (msgtype)
 {
  case "text":
  sendtextcase(requestxml);//发送文本消息
  break;
  case "event"://发送事件消息
  if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("subscribe"))
  {
  sendwelcomemsg(requestxml);//关注时返回的图文消息
  }
  else if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("click"))
  {
  sendeventmsg(requestxml);//发送事件消息
  }
  break;

         case "voice":
  sendvoicemsg(requestxml);//发送语音消息
  break;
  case "location"://发送位置消息
  sendmapmsg(requestxml);
  break;
  default:
  break;

 }
 }
 catch (exception ex)
 {
 httpcontext.current.response.write(ex.tostring());
 }
 }

先来关注发送文本消息,sendtextcase(requestxml);//发送文本消息

 /// <summary>
 /// 发送文本
 /// </summary>
 /// <param name="requestxml"></param>
 private void sendtextcase(requestxml requestxml)
 {
  string responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername, requestxml.content);

  httpcontext.current.response.contenttype = "text/xml";
  httpcontext.current.response.contentencoding = encoding.utf8;
  httpcontext.current.response.write(responsecontent);
  httpcontext.current.response.end();
 }

 formattextxml方法制定格式

 

 /// <summary>
 /// 返回格式化的xml格式内容
 /// </summary>
 /// <param name="p1">公众号</param>
 /// <param name="p2">用户号</param>
 /// <param name="p3">回复内容</param>
 /// <returns></returns>
 private string formattextxml(string p1, string p2, string p3)
 {
 return "<xml><tousername><![cdata[" + p1 + "]]></tousername><fromusername><![cdata[" + p2 + "]]></fromusername><createtime>" + datetime.now.subtract(new datetime(1970, 1, 1, 8, 0, 0)).totalseconds.tostring() + "</createtime><msgtype><![cdata[text]]></msgtype><content><![cdata[" + p3 + "]]></content><funcflag>1</funcflag></xml>";
 }

 

这样就能实现消息的应答,如果用户点击的按钮,如下代码:

 case "event"://发送事件消息
  if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("subscribe"))
  {
  sendwelcomemsg(requestxml);//关注时返回的图文消息
  }
  else if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("click"))
  {
  sendeventmsg(requestxml);//发送事件消息
  }
  break;

 /// <summary>
 /// 发送响应事件消息
 /// </summary>
 /// <param name="requestxml"></param>
 private void sendeventmsg(requestxml requestxml)
 {
 string keystr = requestxml.eventkey.tostring();

 switch (keystr)
 {
 case "mypay":
  sendpaydetails(requestxml);//发送薪资账单
  break;
 case "tianqiyubao":
  sendweatermessage(requestxml);//发送天气预报
  break;
 case "kaixinyixiao":
  sendkaixinmessage(requestxml);//发送开心一笑结果集
  break;
 case "updatemessage":
  sendupdatemessage(requestxml);//发送修改信息链接
  break;
 case "yuangonghuodong":
  sendyuangonghuodong(requestxml);//发送学生活动
  break;
 case "yuangongtongzhi":
  sendyuangongtongzhi(requestxml);//发送员工通知
  break;
 case "youwenbida":
  sendwenti(requestxml);//发送员工提交问题链接
  break;
 case "mywen":
  sendwentilist(requestxml);//发送问题列表链接
  break;
 case "phoneserices":
  sendkefumessage(requestxml);//接入客服
  break;
 default:
  string responsecontent = string.empty;
  responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername,"此功能暂未开放!敬请期待!");
  httpcontext.current.response.contenttype = "text/xml";
  httpcontext.current.response.contentencoding = encoding.utf8;
  httpcontext.current.response.write(responsecontent);
  httpcontext.current.response.end();
  break;
 }
 }

 sendwelcomemsg(requestxml);//关注时返回的图文消息

 /// <summary>
 /// 发送关注时的图文消息
 /// </summary>
 /// <param name="requestxml"></param>
 private void sendwelcomemsg(requestxml requestxml)
 {
 string responsecontent = string.empty;

 string newdate = datetime.now.subtract(new datetime(1970, 1, 1, 8, 0, 0)).totalseconds.tostring();


 string purlfilename = "http://www.deqiaohr.com.cn/weixin/welcome.jpg";

 responsecontent = string.format(message_news_main, requestxml.fromusername, requestxml.tousername, newdate, "1",
 string.format(message_news_item, "欢迎关注德桥员工服务中心", "苏州德桥人力资源创立于2002年...", purlfilename, "http://www.deqiaohr.com.cn/weixin/wxgsjianjie.aspx"));


 httpcontext.current.response.contenttype = "text/xml";
 httpcontext.current.response.contentencoding = encoding.utf8;
 httpcontext.current.response.write(responsecontent);
 httpcontext.current.response.end();
 }

 message_news_main 和message_news_item是图文消息格式化

 /// <summary>
 /// 返回图文消息主体
 /// </summary>
 public static string message_news_main
 {
 get
 {
 return @"<xml>
  <tousername><![cdata[{0}]]></tousername>
  <fromusername><![cdata[{1}]]></fromusername>
  <createtime>{2}</createtime>
  <msgtype><![cdata[news]]></msgtype>
  <articlecount>{3}</articlecount>
  <articles>
  {4}
  </articles>
  </xml> ";
 }
 }
 /// <summary>
 /// 返回图文消息项
 /// </summary>
 public static string message_news_item
 {
 get
 {
 return @"<item>
  <title><![cdata[{0}]]></title> 
  <description><![cdata[{1}]]></description>
  <picurl><![cdata[{2}]]></picurl>
  <url><![cdata[{3}]]></url>
  </item>";
 }
 }

 /// <summary>
 /// 发送响应语音识别结果
 /// </summary>
 /// <param name="requestxml"></param>
 private void sendvoicemsg(requestxml requestxml)
 {
 string responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername, "您刚才说的语音消息识别结果为:" + requestxml.recognition.tostring());
 httpcontext.current.response.contenttype = "text/xml";
 httpcontext.current.response.contentencoding = encoding.utf8;
 httpcontext.current.response.write(responsecontent);
 httpcontext.current.response.end();
 }

精彩专题分享:asp.net微信开发教程汇总,欢迎大家学习。

以上就是关于asp.net微信开发的第二篇,针对消息应答进行学习,之后会有更新更多关于asp.net微信开发的文章,希望大家持续关注。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网