微信公眾平臺開發(fā)教程(三) 基礎(chǔ)框架搭建
首先我們設(shè)計(jì)了模塊層次圖,當(dāng)然圖中只是給出一種實(shí)現(xiàn)方式,不局限于此。具體見下圖。
主要功能介紹如下:
1)請求接口層。處理HTTP請求,及響應(yīng)
2)分發(fā)層。由接口層傳入請求,然后具體分析請求類型,分發(fā)至不同的處理器
3)業(yè)務(wù)邏輯層。這里是我們的具體業(yè)務(wù)邏輯了,根據(jù)請求,實(shí)現(xiàn)具體的業(yè)務(wù)邏輯。
4)數(shù)據(jù)層。我們在實(shí)現(xiàn)某個應(yīng)用時可能需要訪問數(shù)據(jù),可以是數(shù)據(jù)庫或者是文件。如果是簡單應(yīng)用,可能沒有這一層。
其實(shí),具體的應(yīng)用可以在這個結(jié)構(gòu)上去擴(kuò)展,可以擴(kuò)展消息對象層、業(yè)務(wù)對象層、數(shù)據(jù)訪問層、功能管理層等。這里只是提供一種思路,不局限于此。
根據(jù)層次圖,設(shè)計(jì)流程圖,具體講述實(shí)現(xiàn)的各個過程。以便了解整個處理過程。如下圖所示:
根據(jù)流程圖,我們能夠清晰的了解整個流程,消息處理的具體實(shí)現(xiàn)步驟。
下面我們針對每個流程進(jìn)行代碼實(shí)現(xiàn)。
一、接收HTTP請求
我們需要一個HttpHandler或者一個網(wǎng)頁,來處理微信服務(wù)端HTTP請求。
這里我們使用了HttpHandler。因?yàn)槠潇`活性高,性能好。
具體實(shí)現(xiàn)如下。
public class WeiXinHttpHandler:IHttpHandler
{
/// <summary>
///
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 處理請求
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
//由微信服務(wù)接收請求,具體處理請求
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();
}
}
如果是HTTPHandler,需要在配置文件中,配置具體的應(yīng)用。具體的節(jié)點(diǎn)配置,我們不作說明。直接給出例子,配置HttpHandler節(jié)點(diǎn)如下
<httpHandlers> <add verb="*" path="WXService.ashx" type="namespace.WeiXinHttpHandler,WXWeb" validate="true"/> </httpHandlers>
二、分發(fā)請求
為了能功能封裝,我們也將此封裝在了處理組件中。其實(shí)可以放置在HttpHandler中的。
1)驗(yàn)證簽名
如果是首次請求,需要驗(yàn)證簽名。就相當(dāng)于一次HTTP握手。之前在上一章中,設(shè)置的服務(wù)器URL以及token值,這個功能就是檢驗(yàn)是否鏈接成功。
這個請求是GET請求。以下具體說明(官方):
業(yè)務(wù)邏輯:
加密/校驗(yàn)流程:
<1> 將token、timestamp、nonce三個參數(shù)進(jìn)行字典序排序
<2> 將三個參數(shù)字符串拼接成一個字符串進(jìn)行SHA1加密
<3> 開發(fā)者獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信
而官方只提供了PHP的代碼示例,很多東西在C#中并非直譯既得。所以這里面也有一些具體處理。先看官方的代碼:
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
我們將其翻譯成C#版本:
/// <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;
}
}
這里需要SHA1加密,具體的算法如下:
/// <summary>
/// SHA1加密
/// </summary>
/// <param name="intput">輸入字符串</param>
/// <returns>加密后的字符串</returns>
public static string SHA1Encrypt(string intput)
{
byte[] StrRes = Encoding.Default.GetBytes(intput);
HashAlgorithm mySHA = new SHA1CryptoServiceProvider();
StrRes = mySHA.ComputeHash(StrRes);
StringBuilder EnText = new StringBuilder();
foreach (byte Byte in StrRes)
{
EnText.AppendFormat("{0:x2}", Byte);
}
return EnText.ToString();
}
2)分發(fā)請求
接下來就是具體的消息請求了,這里都是POST請求。
因?yàn)橛卸喾N消息類型,我們通過工廠類來進(jìn)行封裝,然后每種消息都有專門的處理器來進(jìn)行處理。具體實(shí)現(xiàn)邏輯:
/// <summary>
/// 處理請求
/// </summary>
/// <returns></returns>
private string ResponseMsg()
{
string requestXml = Common.ReadRequest(this.Request);
IHandler handler = HandlerFactory.CreateHandler(requestXml);
if (handler != null)
{
return handler.HandleRequest();
}
return string.Empty;
}
處理請求的對外方法(HttpHandler調(diào)用的方法就是這個了),即:
/// <summary>
/// 處理請求,產(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 "無法處理";
}
}
三、消息處理器具體處理消息
1)消息類型
首先我們來看下,具體的消息類型,其實(shí)上一張中已經(jīng)明確給了消息的接口。
這里再看具體看一下,請求的消息類型有哪些,回復(fù)的消息類型有哪些等。
千萬要注意,請求的消息是文本類型,回復(fù)的消息,不一定也是文本哦,可以是圖文、音樂等任意一種可回復(fù)的消息。具體見下表所示。
2)根據(jù)具體的消息接口,設(shè)計(jì)消息類。
這里給出類圖,供參考。
3)針對不同的消息,會有不同的處理器,來看下具體的類圖。
4)具體業(yè)務(wù)處理
每個handler里面就是可以處理具體請求。輸入的什么消息,訪問那些數(shù)據(jù),調(diào)用服務(wù)等,都在這里處理。
還是建議大家對具體的業(yè)務(wù)進(jìn)行單獨(dú)封裝,在Handler中,只提供調(diào)用的接口。
因?yàn)殡S著業(yè)務(wù)的增加,一個Handler可能要處理很多業(yè)務(wù),如果所有的操作邏輯都寫在這里,勢必影響閱讀,也不易于維護(hù)與擴(kuò)展。
5)產(chǎn)生回復(fù)消息
在處理完請求后,需要生成回復(fù)消息,響應(yīng)到終端。消息格式,就是我們介紹那些消息類型,但必須是可用于回復(fù)的,當(dāng)前支持的有:文本、圖文、音樂等。
一定要明確:回復(fù)的消息類型不一定要與請求的消息類型一樣,比如,請求是文本,回復(fù)的可以是圖文、音樂。
產(chǎn)生回復(fù)消息的過程,其實(shí),就是特定的消息對象格式化為對應(yīng)的XML的過程,然后將XML響應(yīng)至微信服務(wù)器。
6)實(shí)例
這里以微信用戶關(guān)注公眾賬號,然后服務(wù)端處理處理事件請求,登記用戶,并提示歡迎信息。
class EventHandler : IHandler
{
/// <summary>
/// 請求的xml
/// </summary>
private string RequestXml { get; set; }
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
/// <param name="requestXml"></param>
public EventHandler(string requestXml)
{
this.RequestXml = requestXml;
}
/// <summary>
/// 處理請求
/// </summary>
/// <returns></returns>
public string HandleRequest()
{
string response = string.Empty;
EventMessage em = EventMessage.LoadFromXml(RequestXml);
if (em.Event == EventType.Subscribe)
{
//注冊用戶
User user = new User();
user.OpenID = em.FromUserName;
UserManager.Regester(user);
//回復(fù)歡迎消息
TextMessage tm = new TextMessage();
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = Common.GetNowTime();
tm.Content = "歡迎您關(guān)注xxx,我是小微。有什么我能幫助您的嗎?";
response = tm.GenerateContent();
}
return response;
}
}
四、HTTP響應(yīng)
最后將處理結(jié)果返回至最初HttpHandler,響應(yīng)給微信服務(wù)器,直接Response處理。這也是在最開始設(shè)計(jì)的HttpHandler中實(shí)現(xiàn)的。
下面是代碼片段,具體可見一、Http請求
context.Response.Clear(); context.Response.Charset = "UTF-8"; context.Response.Write(responseMsg); context.Response.End();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:C#中實(shí)現(xiàn)Json序列化與反序列化的幾種方式
欄 目:C#教程
本文標(biāo)題:微信公眾平臺開發(fā)教程(三) 基礎(chǔ)框架搭建
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6150.html
您可能感興趣的文章
- 01-10微信開放平臺之網(wǎng)站授權(quán)微信登錄功能
- 01-10C#微信開發(fā)(服務(wù)器配置)
- 01-10C#微信公眾平臺開發(fā)之高級群發(fā)接口
- 01-10C#微信公眾平臺開發(fā)之a(chǎn)ccess
- 01-10C#微信開發(fā)之微信公眾號標(biāo)簽管理功能
- 01-10C#微信公眾號與訂閱號接口開發(fā)示例代碼
- 01-10C#微信開發(fā)第一章
- 01-10C#實(shí)現(xiàn)的微信網(wǎng)頁授權(quán)操作邏輯封裝示例
- 01-10WPF微信聊天和通訊錄按鈕樣式代碼分享
- 01-10使用TypeScript開發(fā)微信小程序的方法


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子


