.NET微信公眾號(hào)開發(fā)之公眾號(hào)消息處理
一.前言
微信公眾平臺(tái)的消息處理還是比較完善的,有最基本的文本消息,到圖文消息,到圖片消息,語音消息,視頻消息,音樂消息其基本原理都是一樣的,只不過所post的xml數(shù)據(jù)有所差別,在處理消息之前,我們要認(rèn)真閱讀,官方給我們的文檔:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我們從最基本的文本消息處理開始。
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content> </xml>
我們可以看到這是消息處理的一個(gè)最基本的模式,有發(fā)送者,接受者,創(chuàng)建時(shí)間,類型,內(nèi)容等等。
首先我們來創(chuàng)建一個(gè)消息處理的類,這個(gè)類用來捕獲,所有的消息請(qǐng)求,根據(jù)不同的消息請(qǐng)求類型來處理不同的消息回復(fù)。
public class WeiXinService
{
/// <summary>
/// TOKEN
/// </summary>
private const string TOKEN = "finder";
/// <summary>
/// 簽名
/// </summary>
private const string SIGNATURE = "signature";
/// <summary>
/// 時(shí)間戳
/// </summary>
private const string TIMESTAMP = "timestamp";
/// <summary>
/// 隨機(jī)數(shù)
/// </summary>
private const string NONCE = "nonce";
/// <summary>
/// 隨機(jī)字符串
/// </summary>
private const string ECHOSTR = "echostr";
/// <summary>
///
/// </summary>
private HttpRequest Request { get; set; }
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
/// <param name="request"></param>
public WeiXinService(HttpRequest request)
{
this.Request = request;
}
/// <summary>
/// 處理請(qǐng)求,產(chǎn)生響應(yīng)
/// </summary>
/// <returns></returns>
public string Response()
{
string method = Request.HttpMethod.ToUpper();
//驗(yàn)證簽名
if (method == "GET")
{
if (CheckSignature())
{
return Request.QueryString[ECHOSTR];
}
else
{
return "error";
}
}
//處理消息
if (method == "POST")
{
return ResponseMsg();
}
else
{
return "無法處理";
}
}
/// <summary>
/// 處理請(qǐng)求
/// </summary>
/// <returns></returns>
private string ResponseMsg()
{
string requestXml = CommonWeiXin.ReadRequest(this.Request);
IHandler handler = HandlerFactory.CreateHandler(requestXml);
if (handler != null)
{
return handler.HandleRequest();
}
return string.Empty;
}
/// <summary>
/// 檢查簽名
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private bool CheckSignature()
{
string signature = Request.QueryString[SIGNATURE];
string timestamp = Request.QueryString[TIMESTAMP];
string nonce = Request.QueryString[NONCE];
List<string> list = new List<string>();
list.Add(TOKEN);
list.Add(timestamp);
list.Add(nonce);
//排序
list.Sort();
//拼串
string input = string.Empty;
foreach (var item in list)
{
input += item;
}
//加密
string new_signature = SecurityUtility.SHA1Encrypt(input);
//驗(yàn)證
if (new_signature == signature)
{
return true;
}
else
{
return false;
}
}
}
在來看看我們的首先是如何捕獲消息的。首頁Default.ashx的代碼如下
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
string postString = string.Empty;
if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
{
//由微信服務(wù)接收請(qǐng)求,具體處理請(qǐng)求
WeiXinService wxService = new WeiXinService(context.Request);
string responseMsg = wxService.Response();
context.Response.Clear();
context.Response.Charset = "UTF-8";
context.Response.Write(responseMsg);
context.Response.End();
}
else
{
string token = "wei2414201";
if (string.IsNullOrEmpty(token))
{
return;
}
string echoString = HttpContext.Current.Request.QueryString["echoStr"];
string signature = HttpContext.Current.Request.QueryString["signature"];
string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
string nonce = HttpContext.Current.Request.QueryString["nonce"];
if (!string.IsNullOrEmpty(echoString))
{
HttpContext.Current.Response.Write(echoString);
HttpContext.Current.Response.End();
}
}
}
從上面的代碼中我們可以看到WeiXinService.cs類中的消息相應(yīng)至關(guān)重要。
/// <summary>
/// 處理請(qǐng)求
/// </summary>
/// <returns></returns>
private string ResponseMsg()
{
string requestXml = CommonWeiXin.ReadRequest(this.Request);
IHandler handler = HandlerFactory.CreateHandler(requestXml);
if (handler != null)
{
return handler.HandleRequest();
}
return string.Empty;
}
IHandler是一個(gè)消息處理接口,其下面有EventHandler,TextHandler處理類實(shí)現(xiàn)這個(gè)接口。代碼如下
/// <summary>
/// 處理接口
/// </summary>
public interface IHandler
{
/// <summary>
/// 處理請(qǐng)求
/// </summary>
/// <returns></returns>
string HandleRequest();
}
EventHandler
class EventHandler : IHandler
{
/// <summary>
/// 請(qǐng)求的xml
/// </summary>
private string RequestXml { get; set; }
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
/// <param name="requestXml"></param>
public EventHandler(string requestXml)
{
this.RequestXml = requestXml;
}
/// <summary>
/// 處理請(qǐng)求
/// </summary>
/// <returns></returns>
public string HandleRequest()
{
string response = string.Empty;
EventMessage em = EventMessage.LoadFromXml(RequestXml);
if (em.Event.Equals("subscribe", StringComparison.OrdinalIgnoreCase))//用來判斷是不是首次關(guān)注
{
PicTextMessage tm = new PicTextMessage();//我自己創(chuàng)建的一個(gè)圖文消息處理類
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = CommonWeiXin.GetNowTime();
response = tm.GenerateContent();
}
return response;
}
}
TextHandler
/// <summary>
/// 文本信息處理類
/// </summary>
public class TextHandler : IHandler
{
string openid { get; set; }
string access_token { get; set; }
/// <summary>
/// 請(qǐng)求的XML
/// </summary>
private string RequestXml { get; set; }
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
/// <param name="requestXml">請(qǐng)求的xml</param>
public TextHandler(string requestXml)
{
this.RequestXml = requestXml;
}
/// <summary>
/// 處理請(qǐng)求
/// </summary>
/// <returns></returns>
public string HandleRequest()
{
string response = string.Empty;
TextMessage tm = TextMessage.LoadFromXml(RequestXml);
string content = tm.Content.Trim();
if (string.IsNullOrEmpty(content))
{
response = "您什么都沒輸入,沒法幫您啊。";
}
else
{
string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
AccessToken token = AccessToken.Get(username);
access_token = token.access_token;
openid = tm.FromUserName;
response = HandleOther(content);
}
tm.Content = response;
//進(jìn)行發(fā)送者、接收者轉(zhuǎn)換
string temp = tm.ToUserName;
tm.ToUserName = tm.FromUserName;
tm.FromUserName = temp;
response = tm.GenerateContent();
return response;
}
/// <summary>
/// 處理其他消息
/// </summary>
/// <param name="tm"></param>
/// <returns></returns>
private string HandleOther(string requestContent)
{
string response = string.Empty;
if (requestContent.Contains("你好") || requestContent.Contains("您好"))
{
response = "您也好~";
}else if (requestContent.Contains("openid") || requestContent.Contains("id") || requestContent.Contains("ID"))//用來匹配用戶輸入的關(guān)鍵字
{
response = "你的Openid: "+openid;
}
else if (requestContent.Contains("token") || requestContent.Contains("access_token"))
{
response = "你的access_token: " + access_token;
}else
{
response = "試試其他關(guān)鍵字吧。";
}
return response;
}
}
HandlerFactory
/// <summary>
/// 處理器工廠類
/// </summary>
public class HandlerFactory
{
/// <summary>
/// 創(chuàng)建處理器
/// </summary>
/// <param name="requestXml">請(qǐng)求的xml</param>
/// <returns>IHandler對(duì)象</returns>
public static IHandler CreateHandler(string requestXml)
{
IHandler handler = null;
if (!string.IsNullOrEmpty(requestXml))
{
//解析數(shù)據(jù)
XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(requestXml);
XmlNode node = doc.SelectSingleNode("/xml/MsgType");
if (node != null)
{
XmlCDataSection section = node.FirstChild as XmlCDataSection;
if (section != null)
{
string msgType = section.Value;
switch (msgType)
{
case "text":
handler = new TextHandler(requestXml);
break;
case "event":
handler = new EventHandler(requestXml);
break;
}
}
}
}
return handler;
}
}
在這里基本的一些類已經(jīng)完成了,現(xiàn)在我們來完成,關(guān)注我們的微信公眾號(hào),我們就發(fā)送一條圖文消息,同時(shí)輸入我們的一些關(guān)鍵字,返回一些消息,比如輸入id返回用戶的openid等等。
二.PicTextMessage
public class PicTextMessage : Message
{
/// <summary>
/// 模板靜態(tài)字段
/// </summary>
private static string m_Template;
/// <summary>
/// 默認(rèn)構(gòu)造函數(shù)
/// </summary>
public PicTextMessage()
{
this.MsgType = "news";
}
/// <summary>
/// 從xml數(shù)據(jù)加載文本消息
/// </summary>
/// <param name="xml"></param>
public static PicTextMessage LoadFromXml(string xml)
{
PicTextMessage tm = null;
if (!string.IsNullOrEmpty(xml))
{
XElement element = XElement.Parse(xml);
if (element != null)
{
tm = new PicTextMessage();
tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value;
tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value;
tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value;
}
}
return tm;
}
/// <summary>
/// 模板
/// </summary>
public override string Template
{
get
{
if (string.IsNullOrEmpty(m_Template))
{
LoadTemplate();
}
return m_Template;
}
}
/// <summary>
/// 生成內(nèi)容
/// </summary>
/// <returns></returns>
public override string GenerateContent()
{
this.CreateTime = CommonWeiXin.GetNowTime();
string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);
return str;
}
/// <summary>
/// 加載模板
/// </summary>
private static void LoadTemplate()
{
m_Template= @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[有位停車歡迎你!]]></Title>
<Description><![CDATA[如有問題請(qǐng)致電400-6238-136或直接在微信留言,我們將第一時(shí)間為您服務(wù)!]]></Description>
<PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl>
<Url><![CDATA[http://www.baidu.com]]></Url>
</item>
</Articles>
</xml> ";
}
}
最后我們的效果如下所示;


以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡
- asp.net微信開發(fā)(永久素材管理)
- asp.net微信開發(fā)(高級(jí)群發(fā)圖文)
- asp.net微信開發(fā)(高級(jí)群發(fā)文本)
- asp.net微信開發(fā)(自定義會(huì)話管理)
- .NET微信公眾號(hào)開發(fā)之準(zhǔn)備工作
- asp.net開發(fā)微信公眾平臺(tái)之驗(yàn)證消息的真實(shí)性
- asp.net開發(fā)微信公眾平臺(tái)之獲取用戶消息并處理
- Android仿微信發(fā)朋友圈瀏覽圖片效果
- 基于js實(shí)現(xiàn)微信發(fā)送好友如何分享到朋友圈、微博
- .Net語言Smobiler開發(fā)之如何仿微信朋友圈的消息樣式
相關(guān)文章
asp.net基于windows服務(wù)實(shí)現(xiàn)定時(shí)發(fā)送郵件的方法
這篇文章主要介紹了asp.net基于windows服務(wù)實(shí)現(xiàn)定時(shí)發(fā)送郵件的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了asp.net調(diào)用Windows系統(tǒng)服務(wù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
在 .NET 項(xiàng)目中復(fù)制資源文件夾到生成目錄的方法
本文主要介紹在使用 Visual Studio 進(jìn)行調(diào)試和發(fā)布時(shí),如何在 .NET 項(xiàng)目中復(fù)制資源文件夾到生成目錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-03-03
使用asp.net的pageDataSource中時(shí)索引問題解決方法
當(dāng)前頁面在數(shù)據(jù)的除第一頁的任何一個(gè)頁面時(shí),重新條件查詢并且是新條件的總頁數(shù)小于剛才查詢得到的頁碼時(shí),就會(huì)出現(xiàn)“索引 20 不是為負(fù)數(shù),就是大于行數(shù)”的類似的錯(cuò)誤2013-04-04
.Net?Core?3.1?Web?API基礎(chǔ)知識(shí)詳解(收藏)
這篇文章主要介紹了.Net?Core?3.1?Web?API基礎(chǔ)知識(shí),本文內(nèi)容篇幅有點(diǎn)長,大家耐心閱讀,此文結(jié)合示例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2022-04-04
Gridview利用DataFormatString屬性設(shè)置數(shù)據(jù)格式的方法
這篇文章主要介紹了Gridview利用DataFormatString屬性設(shè)置數(shù)據(jù)格式的方法,涉及Gridview屬性操作及數(shù)據(jù)格式相關(guān)技巧,需要的朋友可以參考下2016-03-03
在.NET中使用Newtonsoft.Json轉(zhuǎn)換,讀取,寫入的方法介紹
Newtonsoft.Json.JsonConvert類是非微軟提供的一個(gè)JSON序列化和反序列的開源免費(fèi)的類庫2012-08-08
詳解最好的.NET開源免費(fèi)ZIP庫DotNetZip(.NET組件介紹之三)
本篇文章主要介紹了.NET開源免費(fèi)ZIP庫DotNetZip組件的介紹,可以實(shí)現(xiàn)對(duì)文件的壓縮和解壓,有興趣的朋友可以了解一下。2016-12-12

