程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 用c#開發微信(3)基於Senparc.Weixin框架的接收普通消息處理 (源碼下載),

用c#開發微信(3)基於Senparc.Weixin框架的接收普通消息處理 (源碼下載),

編輯:C#入門知識

用c#開發微信(3)基於Senparc.Weixin框架的接收普通消息處理 (源碼下載),


本文講述使用Senparc.Weixin框架來快速處理各種接收的普通消息。這裡的消息指的是傳統的微信公眾平台消息交互,微信用戶向公眾號發送消息後,公眾號回復消息給微信用戶。包括以下7種類型:

1 文本消息
2 圖片消息
3 語音消息
4 視頻消息
5 小視頻消息
6 地理位置消息
7 鏈接消息

實現非常簡單,自定義一個繼承MessageHandler的類,重寫這7種類型的方法即可。注意:DefaultResponseMessage必須重寫,用於返回沒有處理過的消息類型(也可以用於默認消息,如幫助信息等);其中所有原OnXX的抽象方法已經都改為虛方法,可以不必每個都重寫。若不重寫,默認返回DefaultResponseMessage方法中的結果。

 

下面詳細介紹實現步驟:

1. 添加index頁面

private readonly string Token = ConfigurationManager.AppSettings["token"];//與微信公眾賬號後台的Token設置保持一致,區分大小寫。
       protected void Page_Load(object sender, EventArgs e)
       {
           string signature = Request["signature"];
           string timestamp = Request["timestamp"];
           string nonce = Request["nonce"];
           string echostr = Request["echostr"];
           if (Request.HttpMethod == "GET")
           {
               //get method - 僅在微信後台填寫URL驗證時觸發
               if (CheckSignature.Check(signature, timestamp, nonce, Token))
               {
                   WriteContent(echostr); //返回隨機字符串則表示驗證通過
               }
               else
               {
                   WriteContent("failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, Token) + "。" +
                               "如果你在浏覽器中看到這句話,說明此地址可以被作為微信公眾賬號後台的Url,請注意保持Token一致。");
               }
               Response.End();
           }
           else
           {
               //post method - 當有用戶想公眾賬號發送消息時觸發
               if (!CheckSignature.Check(signature, timestamp, nonce, Token))
               {
                   WriteContent("參數錯誤!");
                   return;
               }
               //設置每個人上下文消息儲存的最大數量,防止內存占用過多,如果該參數小於等於0,則不限制
               var maxRecordCount = 10;
               //自定義MessageHandler,對微信請求的詳細判斷操作都在這裡面。
               var messageHandler = new CustomMessageHandler(Request.InputStream, maxRecordCount);
 
               try
               {
                   //測試時可開啟此記錄,幫助跟蹤數據,使用前請確保App_Data文件夾存在,且有讀寫權限。
                   messageHandler.RequestDocument.Save(
                       Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Request_" +
                                      messageHandler.RequestMessage.FromUserName + ".txt"));
                   //執行微信處理過程
                   messageHandler.Execute();
                   //測試時可開啟,幫助跟蹤數據
                   messageHandler.ResponseDocument.Save(
                       Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Response_" +
                                      messageHandler.ResponseMessage.ToUserName + ".txt"));
                   WriteContent(messageHandler.ResponseDocument.ToString());
                   return;
               }
               catch (Exception ex)
               {
                   //將程序運行中發生的錯誤記錄到App_Data文件夾
                   using (TextWriter tw = new StreamWriter(Server.MapPath("~/App_Data/Error_" + DateTime.Now.Ticks + ".txt")))
                   {
                       tw.WriteLine(ex.Message);
                       tw.WriteLine(ex.InnerException.Message);
                       if (messageHandler.ResponseDocument != null)
                       {
                           tw.WriteLine(messageHandler.ResponseDocument.ToString());
                       }
                       tw.Flush();
                       tw.Close();
                   }
                   WriteContent("");
               }
               finally
               {
                   Response.End();
               }
           }
       }
       private void WriteContent(string str)
       {
           Response.Output.Write(str);
       }

 

1)當Get請求時,調用 CheckSignature.Check(signature, timestamp, nonce, Token) 方法驗證url接入, 詳情參考 用c#開發微信(1)服務號的服務器配置和企業號的回調模式 - url接入 (源碼下載)

2)  當有Post請求過來時,調用自定義MessageHandler類,對微信請求的詳細判斷操作都在這裡面。

var messageHandler = new CustomMessageHandler(Request.InputStream, maxRecordCount);

messageHandler.Execute();

 

2. 自定義消息處理類

定義CustomMessageHandler繼承MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>

public partial class CustomMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>
{
    public CustomMessageHandler(Stream inputStream, int maxRecordCount = 0)
        : base(inputStream, null, maxRecordCount)
    {
        WeixinContext.ExpireMinutes = 3;
    }
    public override void OnExecuting()
    {
        //測試MessageContext.StorageData
        if (CurrentMessageContext.StorageData == null)
        {
            CurrentMessageContext.StorageData = 0;
        }
        base.OnExecuting();
    }
    public override void OnExecuted()
    {
        base.OnExecuted();
        CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1;
    }
}

 

3. 分別重寫7種接收普通消息

我們可以通過重寫MessageHandler裡的這7種類型方法來處理我們的業務,當然也可以只重寫需要的部分類型,不需要的類型可以不重寫,只需要定義一個統一的DefaultResponseMessage

public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
    //所有沒有被處理的消息會默認返回這裡的結果
    var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "這條消息來自DefaultResponseMessage。";
    return responseMessage;
}

 

下面分別就這7種類型,各寫一個例子:

1) 文本消息
/// <summary>
/// 處理文字請求
/// </summary>
/// <returns></returns>
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
    //注意:下面泛型ResponseMessageText即返回給客戶端的類型,可以根據自己的需要填寫ResponseMessageNews等不同類型。
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
 
    var result = new StringBuilder();
    result.AppendFormat("您剛才發送了文字信息:{0}\r\n\r\n", requestMessage.Content);
 
    if (CurrentMessageContext.RequestMessages.Count > 1)
    {
        result.AppendFormat("您剛才還發送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData);
        for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--)
        {
            var historyMessage = CurrentMessageContext.RequestMessages[i];
            result.AppendFormat("{0} 【{1}】{2}\r\n",
                                historyMessage.CreateTime.ToShortTimeString(),
                                historyMessage.MsgType.ToString(),
                                (historyMessage is RequestMessageText)
                                    ? (historyMessage as RequestMessageText).Content
                                    : "[非文字類型]"
                );
        }
        result.AppendLine("\r\n");
    }
    result.AppendFormat("如果您在{0}分鐘內連續發送消息,記錄將被自動保留(當前設置:最多記錄{1}條)。過期後記錄將會自動清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount);
    result.AppendLine("\r\n");
    result.AppendLine("您還可以發送【位置】【圖片】【語音】【視頻】等類型的信息(注意是這幾種類型,不是這幾個文字),查看不同格式的回復。");
    responseMessage.Content = result.ToString();
    return responseMessage;
}

 

 

2) 圖片消息
/// <summary>
/// 處理圖片請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage)
{
var responseMessage = CreateResponseMessage<ResponseMessageNews>();
responseMessage.Articles.Add(new Article()
{
    Title = "您剛才發送了圖片信息",
    Description = "您發送的圖片將會顯示在邊上",
    PicUrl = requestMessage.PicUrl,
    Url = "http://www.hp.com"
});
responseMessage.Articles.Add(new Article()
{
    Title = "第二條",
    Description = "第二條帶連接的內容",
    PicUrl = requestMessage.PicUrl,
    Url = "http://www.hp.com"
});
return responseMessage;
}

 

3) 語音消息
/// <summary>
/// 處理語音請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageMusic>();
    responseMessage.Music.MusicUrl = "http://www.qxuninfo.com/music.mp3";
    responseMessage.Music.Title = "這裡是一條音樂消息";
    responseMessage.Music.Description = "時間都去哪兒了";
    return responseMessage;
}

 

4) 視頻消息
/// <summary>
/// 處理視頻請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "您發送了一條視頻信息,ID:" + requestMessage.MediaId;
    return responseMessage;
}

 

5) 小視頻消息
/// <summary>
/// 處理小視頻請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnShortVideoRequest(RequestMessageShortVideo requestMessage)
{
    var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "您剛才發送的是小視頻";
    return responseMessage;
}

 

6) 地理位置消息
/// <summary>
/// 處理位置請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = string.Format("您剛才發送了地理位置信息。Location_X:{0},Location_Y:{1},Scale:{2},標簽:{3}",
                      requestMessage.Location_X, requestMessage.Location_Y,
                      requestMessage.Scale, requestMessage.Label);
    return responseMessage;
}

 

7) 鏈接消息
/// <summary>
/// 處理鏈接消息請求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = string.Format(@"您發送了一條連接信息:
Title:{0} 
Description:{1}
Url:{2}", requestMessage.Title, requestMessage.Description, requestMessage.Url);
    return responseMessage;
}

 

 

從上面的例子中可以看出,回復的消息類型可以多種多樣,不一定要跟請求的消息類型一樣。

 

  • 框架裡的請求類型:

用c#開發微信 系列匯總

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved