接收普通消息
普通消息是指員工向企業號應用發送的消息,包括文本、圖片、語音、視頻、地理位置等類型。普通消息會推送到每個應用在管理端設置的URL(以下假設該URL為http://api.3dept.com)。
- 請求說明
Http請求方式: POST
http://api.3dept.com/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS×tamp=13500001234&nonce=123412323
text消息
<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> <AgentID>1</AgentID> </xml>
參數 | 說明 |
---|---|
ToUserName | 企業號CorpID |
FromUserName | 員工UserID |
CreateTime | 消息創建時間(整型) |
MsgType | 消息類型,此時固定為:text |
Content | 文本消息內容 |
MsgId | 消息id,64位整型 |
AgentID | 企業應用的id,整型。可在應用的設置頁面查看 |
image消息
<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> <AgentID>1</AgentID> </xml>
參數 | 說明 |
---|---|
ToUserName | 企業號CorpID |
FromUserName | 員工UserID |
CreateTime | 消息創建時間(整型) |
MsgType | 消息類型,此時固定為:image |
PicUrl | 圖片鏈接 |
MediaId | 圖片媒體文件id,可以調用獲取媒體文件接口拉取數據 |
MsgId | 消息id,64位整型 |
AgentID | 企業應用的id,整型。可在應用的設置頁面查看 |
voice消息
<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> <AgentID>1</AgentID> </xml>
參數 | 說明 |
---|---|
ToUserName | 企業號CorpID |
FromUserName | 員工UserID |
CreateTime | 消息創建時間(整型) |
MsgType | 消息類型,此時固定為:voice |
MediaId | 語音媒體文件id,可以調用獲取媒體文件接口拉取數據 |
Format | 語音格式,如amr,speex等 |
MsgId | 消息id,64位整型 |
AgentID | 企業應用的id,整型。可在應用的設置頁面查看 |
video消息
<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> <AgentID>1</AgentID> </xml>
參數 | 說明 |
---|---|
ToUserName | 企業號CorpID |
FromUserName | 員工UserID |
CreateTime | 消息創建時間(整型) |
MsgType | 消息類型,此時固定為:video |
MediaId | 視頻媒體文件id,可以調用獲取媒體文件接口拉取數據 |
ThumbMediaId | 視頻消息縮略圖的媒體id,可以調用獲取媒體文件接口拉取數據 |
MsgId | 消息id,64位整型 |
AgentID | 企業應用的id,整型。可在應用的設置頁面查看 |
location消息
<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> <AgentID>1</AgentID> </xml>
參數 | 說明 |
---|---|
ToUserName | 企業號CorpID |
FromUserName | 員工UserID |
CreateTime | 消息創建時間(整型) |
MsgType | 消息類型,此時固定為:location |
Location_X | 地理位置緯度 |
Location_Y | 地理位置經度 |
Scale | 地圖縮放大小 |
Label | 地理位置信息 |
MsgId | 消息id,64位整型 |
AgentID | 企業應用的id,整型。可在應用的設置頁面查看 |
---------------------------------------日志開始----------------------------------------------------------
整個被動響應的代碼圖如下
根據以上信息,我們創建如下幾個類,
分組代碼圖:
類圖:
RequestBase為所有接受信息基類,普通消息可直接繼承
RequestEvent繼承RequestBase,為事件消息的基類
微信接收信息分兩種:
一種是接收普通消息(直接繼承RequestBase類)
另一種是接收事件(繼承RequestEvent類)
微信的消息類型結構如圖所示
RequestBase.cs
/// <summary> /// 接受消息基類 /// </summary> public class RequestBase { public bool LoadStatus = true; public string ErrorMsg = String.Empty; /// <summary> /// 如果消息類型或消息事件沒處理,通過這個構造實例化XML_Request對象 /// </summary> /// <param name="table"></param> /// <param name="LoaderrorMsg"></param> public RequestBase(Dictionary<string, string> table, string LoaderrorMsg) { this.ToUserName = table["ToUserName"]; this.FromUserName = table["FromUserName"]; this.CreateTime = table["CreateTime"]; this.MsgType = table["MsgType"]; this.AgentID = table["AgentID"]; LoadStatus = false; ErrorMsg = LoaderrorMsg; } public RequestBase(Dictionary<string, string> table) { this.ToUserName = table["ToUserName"]; this.FromUserName = table["FromUserName"]; this.CreateTime = table["CreateTime"]; this.MsgType = table["MsgType"]; this.AgentID = table["AgentID"]; } /// <summary> /// 微信企業號 /// </summary> public string ToUserName { set; get; } /// <summary> /// 員工UserID /// </summary> public string FromUserName { set; get; } /// <summary> /// 消息創建時間 (整型) /// </summary> public string CreateTime { set; get; } /// <summary> /// 消息類型 /// </summary> public string MsgType { set; get; } /// <summary> /// 應用程序ID /// </summary> public string AgentID { set; get; } }
RequestText.cs
/// <summary> /// 文本消息 /// </summary> public class RequestText : RequestBase { /* <xml> <ToUserName><![CDATA[wx78fc2f1a2c006ec1]]></ToUserName> <FromUserName><![CDATA[garson_zhang@163.com]]></FromUserName> <CreateTime>1413269690</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[22]]></Content> <MsgId>4634274969423970332</MsgId> <AgentID>1</AgentID> </xml> */ public RequestText(Dictionary<string, string> table) : base(table) { this.Content = table["Content"]; this.MsgId = table["MsgId"]; } public string Content { set; get; } public string MsgId { set; get; } }
RequestEvent.cs
/// <summary> /// 上報菜單事件 /// </summary> public class RequestEvent : RequestBase { public RequestEvent(Dictionary<string, string> table) : base(table) { this.Event = table["Event"]; } public string Event { set; get; } }
RequestEvent_Click.cs
/// <summary> /// 上報菜單點擊事件 /// </summary> public class RequestEvent_Click : RequestEvent { /* <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[CLICK]]></Event> <EventKey><![CDATA[EVENTKEY]]></EventKey> <AgentID>1</AgentID> </xml> */ public RequestEvent_Click(Dictionary<string, string> table) : base(table) { //this.ToUserName = table["ToUserName"]; //this.FromUserName = table["FromUserName"]; //this.CreateTime = table["CreateTime"]; //this.MsgType = table["MsgType"]; this.EventKey = table["EventKey"]; } public string EventKey { set; get; } }
LoadXML.cs,把XML子付出啊轉換為對應的消息類型
/// </summary> /// 消息工廠 /// </summary> public class LoadXML { public static RequestBase GetRequest(string XML) { XmlDocument doc = new XmlDocument(); doc.LoadXml(XML); XmlNode root = doc.FirstChild; Dictionary<string, string> table = new Dictionary<string, string>(); foreach (XmlNode v in root.ChildNodes) { table.Add(v.Name, v.InnerText); } RequestBase xmlRequest = null; switch (table["MsgType"]) { case RequestMessageType.text: { xmlRequest = new RequestText(table); }; break; case RequestMessageType.fevent: { switch (table["Event"]) { case RequestMessageEventType.click: { xmlRequest = new RequestEvent_Click(table); }; break; default: { xmlRequest = new RequestBase(table, "此點擊事件無效,服務器沒有處理該事件的操作!\r\n事件類型:" + table["Event"]); }; break; } }; break; default: { xmlRequest = new RequestBase(table, "服務器沒有處理該消息的操作!\r\n消息類型:" + table["MsgType"]); }; break; } return xmlRequest; } }
-----------------------------------------------------------功能實現-----------------------------------------------------------------------------------------
定義一個加密解密類,繼承自WXBizMsgCrypt
/// <summary> /// 響應消息,處理中心 /// </summary> public class WXBizMsgCryptAPI : WXBizMsgCrypt { #region 字段屬性 /// <summary> /// Token可由企業任意填寫,用於生成簽名 /// </summary> public string Token { get; set; } /// <summary> /// EncodingAESKey用於消息體的加密,是AES密鑰的Base64編碼 /// </summary> public string EncodingAESKey { get; set; } /// <summary> /// 集團ID /// </summary> public string CorpID { get; set; } /// <summary> /// 微信加密簽名,msg_signature結合了企業填寫的token、請求中的timestamp、nonce參數、加密的消息體 /// </summary> public string msg_signature { get; set; } /// <summary> /// 時間戳,對應URL參數的timestamp /// </summary> public string timestamp { get; set; } /// <summary> /// 隨機串,對應URL參數的nonce /// </summary> public string nonce { get; set; } /// <summary> /// 加密的隨機字符串,以msg_encrypt格式提供。需要解密並返回echostr明文,解密后有random、msg_len、msg、$CorpID四個字段,其中msg即為echostr明文 /// </summary> public string echostr { get; set; } #endregion 字段屬性 public WXBizMsgCryptAPI(string stoken, string sEncodingAESKey, string sCorpID, string signature, string stimestamp, string snonce) : base(stoken, sEncodingAESKey, sCorpID) { Token = stoken; EncodingAESKey = sEncodingAESKey; CorpID = sCorpID; msg_signature = signature; timestamp = stimestamp; nonce = snonce; } /// <summary> /// 檢驗消息的真實性,並且獲取解密后的明文 /// </summary> /// <param name="sReqData">密文,對應POST請求的數據</param> /// <param name="sMsg">解密后的原文,當return返回0時有效</param> /// <returns>成功0,失敗返回對應的錯誤碼</returns> public int DecryptMsg(string sReqData, ref string sMsg) { return this.DecryptMsg(msg_signature, timestamp, nonce, sReqData, ref sMsg); } /// <summary> /// 將企業號回復用戶的消息加密打包 /// </summary> /// <param name="sReplyMsg">企業號待回復用戶的消息,xml格式的字符串</param> /// <param name="sEncryptMsg">加密后的可以直接回復用戶的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,當return返回0時有效</param> /// <returns>成功0,失敗返回對應的錯誤碼</returns> public int EncryptMsg(string sReplyMsg, ref string sEncryptMsg) { return this.EncryptMsg(sReplyMsg, timestamp, nonce, ref sEncryptMsg); } /// <summary> /// 獲得加密后的XML,返回給微信服務器 /// </summary> /// <param name="sReqTimeStamp"></param> /// <param name="sReqNonce"></param> /// <returns></returns> public string GetDocument(string sRespData, string sReqTimeStamp, string sReqNonce) { //string sRespData = xmlPost.GetXML(); string sEncryptMsg = ""; //xml格式的密文 int ret = EncryptMsg(sRespData, sReqTimeStamp, sReqNonce, ref sEncryptMsg); if (ret != 0) { System.Console.WriteLine("ERR: EncryptMsg Fail, ret: " + ret); return ""; } // TODO: // 加密成功,企業需要將加密之后的sEncryptMsg返回 return sEncryptMsg; // HttpUtils.SetResponse(sEncryptMsg); } /// <summary> /// 獲得加密后的XML,返回給微信服務器 /// </summary> /// <returns></returns> public string GetDocument(string sRespData) { //string sRespData = xmlPost.GetXML(); string sEncryptMsg = ""; //xml格式的密文 int ret = EncryptMsg(sRespData, ref sEncryptMsg); if (ret != 0) { System.Console.WriteLine("ERR: EncryptMsg Fail, ret: " + ret); return ""; } // TODO: // 加密成功,企業需要將加密之后的sEncryptMsg返回 return sEncryptMsg; // HttpUtils.SetResponse(sEncryptMsg); } }
消息處理類CustomMessageHandler:
public class CustomMessageHandler { /// <summary> /// 微信企業號相應中心 /// </summary> WXBizMsgCryptAPI apidata; /// <summary> /// 當前消息類 /// </summary> RequestBase CurrentMessage; /// <summary> /// 要返回(響應)的xml文檔 /// </summary> public Response_Base ResponseDocument; /// <summary> /// 是否取消操作,當產生錯誤,或者異常發生的時候,不處理,直接返還錯誤消息 /// </summary> private bool CancelHandle = false; /// <summary> /// 最大上下文消息數 /// </summary> public int MaxMsgContextCount { get; set; } /// <summary> /// 最大命令數 /// </summary> public int MaxCommandContextCount { get; set; } private static MessageContext MsgContext = new MessageContext(MsgContext_MsgContextChanged); /// <summary> /// 這里需要添加的命令 /// </summary> /// <param name="CurrentMsg"></param> private static void MsgContext_MsgContextChanged(RequestBase CurrentMsg) { if (false) MsgContext.InsertCommandContext(CurrentMsg); } public MessageContextHandler CurrentMessageContext { get { return MsgContext.GetMessageContext(CurrentMessage.FromUserName); } } /// <summary> /// 構造函數 /// </summary> /// <param name="sapidata"></param> /// <param name="InputStream"></param> /// <param name="MaxMsgContextCount">最大上下文消息數</param> /// <param name="MaxCommandContextCount">最大上下文命令數</param> public CustomMessageHandler(WXBizMsgCryptAPI sapidata, System.IO.Stream InputStream, int MaxMsgContextCount, int MaxCommandContextCount) { MsgContext.MsgContextMaxCount = MaxMsgContextCount; MsgContext.MsgCommandMaxCount = MaxCommandContextCount; apidata = sapidata; InputStream.Position = 0; StreamReader reader = new StreamReader(InputStream); string sReqData = reader.ReadToEnd();//加密XML信息 string sMsg = ""; // 解析之后的XML明文 //本地調試的時候跳過解密,因為本地調試直接發送的就是未經過加密的xml明文 int ret = apidata.DecryptMsg(sReqData, ref sMsg); //sMsg = sReqData; string tt = String.Format("用戶發送消息解密后的明文:\r\n{0}", sMsg); CommonTools.WriteText(tt); if (ret != 0) { SetResponse.WriteContent("錯誤!"); return; } CurrentMessage = LoadXML.GetRequest(sMsg); if (CurrentMessage.LoadStatus == false) { OnErrorResponse(CurrentMessage); } else MsgContext.InsertMsgContext(CurrentMessage); } /// <summary> /// 處理指令,響應 /// </summary> public void Execute() { if (CancelHandle) return;//終止處理 switch (CurrentMessage.MsgType.ToLower()) { case RequestMessageType.text: { OnTextResponse(CurrentMessage as RequestText); }; break; case RequestMessageType.fevent: { switch ((CurrentMessage as RequestEvent).Event.ToLower()) { case RequestMessageEventType.click: { OnEventResponse_Click(CurrentMessage as RequestEvent_Click); }; break; default: { OnErrorResponse(CurrentMessage.FromUserName, CurrentMessage.ToUserName, "此點擊事件無效,服務器沒有處理該事件的操作!\r\n事件類型:" + RequestMessageType.fevent); }; break; } }; break; default: { OnErrorResponse(CurrentMessage.FromUserName, CurrentMessage.ToUserName, "服務器沒有處理該消息的操作!\r\n消息類型:" + CurrentMessage.MsgType); }; break; } } public string Document { get; set; } #region 響應 /// <summary> /// 回復text消息 /// </summary> /// <param name="Content">指令</param> void OnTextResponse(RequestText currentMessage) { DoTextResponse(currentMessage.FromUserName, currentMessage.ToUserName, currentMessage.Content); } /// <summary> /// 相應點擊菜單事件 /// </summary> /// <param name="currentMessage"></param> void OnEventResponse_Click(RequestEvent_Click currentMessage) { DoTextResponse(currentMessage.FromUserName, currentMessage.ToUserName, currentMessage.EventKey); } /// <summary> /// 回復錯誤消息 /// </summary> /// <param name="Content">指令</param> void OnErrorResponse(RequestBase currentMessage) { CancelHandle = true; SetDocument_Text(currentMessage.FromUserName, currentMessage.ToUserName, currentMessage.ErrorMsg); } /// <summary> /// 回復錯誤消息 /// </summary> /// <param name="Content">指令</param> void OnErrorResponse(string FromUserName, string ToUserName ,string ErrorMsg) { CancelHandle = true; SetDocument_Text(FromUserName, ToUserName, ErrorMsg); } #endregion #region 指令處理 /// <summary> /// 處理文本指令 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="Content"></param> void DoTextResponse(string FromUserName, string ToUserName, string Content) { string xaData = XAData.GetXAData(FromUserName, Content); //string xaData = String.Format("你剛剛發送了:{0}", CurrentMessageContext.Contents[0]); StringBuilder Recodes = new StringBuilder(); //Recodes.AppendFormat("\r\n您一共發送了{0}條消息\r\n", CurrentMessageContext.Contents.Length); //foreach (string str in CurrentMessageContext.Contents) //{ // Recodes.AppendFormat("{0}\r\n", str); //} Recodes.AppendFormat("\r\n<a href=\"http://xinaoknitting.wicp.net:8088/WX/AttendCardTime.aspx?U=" + CurrentMessage.FromUserName + "\">點擊這里</a>查看當月考勤。"); SetDocument_Text(FromUserName, ToUserName, xaData + Recodes.ToString()); } /// <summary> /// 返回Text消 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="xaData"></param> void SetDocument_Text(string FromUserName, string ToUserName, string xaData) { //生成text響應類 Response_Text XML = new Response_Text(FromUserName, ToUserName, xaData); Document = apidata.GetDocument(XML.GetXML()); } #endregion }
MsgRecode
/// <summary> /// 上下文消息標識 /// </summary> public class MsgRecode { /// <summary> /// 微信企業號 /// </summary> public string ToUserName { set; get; } /// <summary> /// 員工UserID /// </summary> public string FromUserName { set; get; } /// <summary> /// 消息創建時間 (整型) /// </summary> public string CreateTime { set; get; } /// <summary> /// 消息類型 /// </summary> public string MsgType { set; get; } /// <summary> /// 應用程序ID /// </summary> public string AgentID { set; get; } /// <summary> /// 消息內容 /// </summary> public string Content { set; get; } }
MessageContextHandler
public class MessageContextHandler { List<MsgRecode> lstMsgContext;//消息上下文 List<MsgRecode> lstCommandContext;//命令上下文 /// <summary> /// 用戶名 /// </summary> public string UserName { get; set; } /// <summary> /// 消息上下文 /// </summary> public string[] Contents { get { return GetContent(lstMsgContext); } } /// <summary> /// 命令上下文 /// </summary> public string[] Commands { get { return GetContent(lstCommandContext); } } public MessageContextHandler(string UserName, List<MsgRecode> MsgContextList, List<MsgRecode> CommandContextList) { this.UserName = UserName; lstMsgContext = MsgContextList; lstCommandContext = CommandContextList; } #region 自定義函數 private string[] GetContent(List<MsgRecode> lst) { string[] tmp = new string[lst.Count]; for (int i = 0; i < lst.Count; i++) tmp[i] = lst[i].Content; return tmp; } #endregion }
MessageContext
public delegate void CurrentMsgContextChanged(RequestBase CurrentMsg); /// <summary> /// 消息上下文 /// </summary> public class MessageContext { Dictionary<string, List<MsgRecode>> dcMsgConText=new Dictionary<string,List<MsgRecode>>(); Dictionary<string, List<MsgRecode>> dcCommandContext=new Dictionary<string,List<MsgRecode>>(); public event CurrentMsgContextChanged MsgContextChanged; public MessageContext(CurrentMsgContextChanged msgContextChanged) { MsgContextChanged = msgContextChanged; } //消息上下文 List<MsgRecode> GetMsgContentContext(string userName) { if (!dcMsgConText.ContainsKey(userName)) dcMsgConText.Add(userName, new List<MsgRecode>()); return dcMsgConText[userName]; } //命令上下文 List<MsgRecode> GetCommandContext(string userName) { if (!dcCommandContext.ContainsKey(userName)) dcCommandContext.Add(userName, new List<MsgRecode>()); return dcCommandContext[userName]; } public MessageContextHandler GetMessageContext(string userName) { var Msg = GetMsgContentContext(userName); var Command = GetCommandContext(userName); MessageContextHandler handler = new MessageContextHandler(userName, Msg, Command); return handler; } private int _msgcontextmaxcount = 1; /// <summary> /// 最大上下文消息樹 /// </summary> public int MsgContextMaxCount { get { return _msgcontextmaxcount; } set { _msgcontextmaxcount = value > 0 ? value : 1; } } private int _msgcommandmaxcount = 1; /// <summary> /// 最大上下文命令數 /// </summary> public int MsgCommandMaxCount { get { return _msgcommandmaxcount; } set { _msgcommandmaxcount = value > 0 ? value : 1; } } /// <summary> /// 添加消息記錄 /// </summary> /// <param name="request"></param> public void InsertMsgContext(RequestBase request) { MsgRecode mr = GetMsgContext(request); IntMsgContentContext(mr); if (MsgContextChanged != null) MsgContextChanged(request); } /// <summary> /// 添加消息記錄 /// </summary> /// <param name="request"></param> /// <param name="IsCommand">是否是命令,如果是命令,則為true,也可以用MsgContextChanged事件來調用</param> public void InsertMsgContext(RequestBase request, bool IsCommand) { MsgRecode mr = GetMsgContext(request); IntMsgContentContext(mr); if (IsCommand == true) InsertCommandContext(request); } /// <summary> /// 添加命令記錄 /// </summary> /// <param name="request"></param> public void InsertCommandContext(RequestBase request) { MsgRecode mr = GetMsgContext(request); IntCommandContext(mr); } #region 自定義輔助函數 void IntMsgContentContext(MsgRecode mr) { var lstMsgContext = GetMsgContentContext(mr.FromUserName); while (lstMsgContext.Count >= MsgContextMaxCount) lstMsgContext.RemoveAt(lstMsgContext.Count); lstMsgContext.Insert(0, mr); } void IntCommandContext(MsgRecode mr) { var lstCommandContext = GetCommandContext(mr.FromUserName); while (lstCommandContext.Count >= MsgCommandMaxCount) lstCommandContext.RemoveAt(lstCommandContext.Count); lstCommandContext.Insert(0, mr); } private MsgRecode GetMsgContext(RequestBase request) { MsgRecode mr = new MsgRecode() { ToUserName = request.ToUserName, FromUserName = request.FromUserName, CreateTime = request.CreateTime, MsgType = request.MsgType, AgentID = request.AgentID }; if (request is RequestText) mr.Content = (request as RequestText).Content; return mr; } #endregion }
/// <summary> /// 被動響應消息基類 /// </summary> public class Response_Base { /// <summary> /// 構造函數 /// </summary> /// <param name="msgType"></param> public Response_Base(string msgType) { this.MsgType = msgType; } ///// <summary> ///// 獲得XML明文 ///// </summary> ///// <returns></returns> //public abstract string GetXML(); /// <summary> /// 員工UserID /// </summary> public string ToUserName { get; set; } /// <summary> /// 企業號CorpID /// </summary> public string FromUserName { get; set; } /// <summary> /// 消息創建時間(整型) /// </summary> public string CreateTime { get; set; } /// <summary> /// 消息類型,:text,image,voice,video,news /// </summary> public string MsgType { get; set; } public virtual string GetXML() { throw new Exception("沒有重寫GetXML方法"); } } /// <summary> /// 被動響應消息text /// </summary> public class Response_Text : Response_Base { /* <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> </xml> */ string xmlformat = @" <xml> <ToUserName><![CDATA[{0}]]></ToUserName> <FromUserName><![CDATA[{1}]]></FromUserName> <CreateTime>{2}</CreateTime> <MsgType><![CDATA[{3}]]></MsgType> <Content><![CDATA[{4}]]></Content> </xml>"; /// <summary> /// 構造函數 /// </summary> /// <param name="toUser">員工UserID </param> /// <param name="fromUser">企業號CorpID </param> /// <param name="content">文本消息內容 </param> /// <param name="createTime">消息創建時間(整型),參考:APITools.GetCreateTime()</param> public Response_Text(string toUser, string fromUser, string content, string createTime) : base(RequestMessageType.text) { this.ToUserName = toUser; this.FromUserName = fromUser; this.Content = content; this.CreateTime = createTime; } /// <summary> /// 構造函數 /// </summary> /// <param name="toUser">員工UserID </param> /// <param name="fromUser">企業號CorpID </param> /// <param name="content">文本消息內容 </param> public Response_Text(string toUser, string fromUser, string content) : base(RequestMessageType.text) { this.ToUserName = toUser; this.FromUserName = fromUser; this.Content = content; this.CreateTime = CorpTools.GetCreateTime(); } /// <summary> /// 獲得XML文本 /// </summary> /// <returns></returns> public override string GetXML() { return String.Format(xmlformat, ToUserName, FromUserName, CreateTime, MsgType, Content); } /// <summary> /// 文本消息內容 /// </summary> public string Content { get; set; } }
代碼貼完了,接下來是接口調用:
public void ProcessRequest(HttpContext context) { WriteText("開始回調:" + context.Request.Url.ToString()); //微信接入的測試 string token = ConfigurationManager.AppSettings["CorpToken"];//從配置文件獲取Token string CorpID = ConfigurationManager.AppSettings["CorpID"];//從配置文件獲取Token string EncodingAESKey = ConfigurationManager.AppSettings["EncodingAESKey"];//從配置文件獲取Token int MaxMsgContextCount = ConvertEx.ToInt(ConfigurationManager.AppSettings["MaxMsgContextCount"], 10);//最大上下文消息數 int MaxCommandContextCount = ConvertEx.ToInt(ConfigurationManager.AppSettings["MaxCommandContextCount"], 3);//最大命令數 string signature = context.Request["msg_signature"]; string timestamp = context.Request["timestamp"]; string nonce = context.Request["nonce"]; if (context.Request.HttpMethod == "GET")//驗證 { WriteText("Get驗證"); string echostr = context.Request["echostr"]; StringBuilder Txt=new StringBuilder(); Txt.Append("Get微信接口驗證\r\n"); Txt.AppendFormat("signature:{0}\r\n", signature); Txt.AppendFormat("timestamp:{0}\r\n", timestamp); Txt.AppendFormat("nonce:{0}\r\n", nonce); Txt.AppendFormat("echostr:{0}\r\n", echostr); Txt.AppendFormat("EncodingAESKey:{0}\r\n", EncodingAESKey); Txt.AppendFormat("CorpID:{0}\r\n", CorpID); Txt.AppendFormat("CorpToken:{0}\r\n", token); CommonTools.WriteText(Txt.ToString()); string sEchoStr = ""; bool check = CheckSignatureQY.Check(signature, timestamp, nonce, echostr , EncodingAESKey, CorpID, ref sEchoStr, token);//True表示成功 //WriteText(check ? "True" : "False"); //check為True成功,Flase失敗,失敗信息在SechoStr CommonTools.WriteText("結果為:" + (check ? "True" : "False")); CommonTools.WriteText("驗證返回字符串為:" + sEchoStr); WriteContent(sEchoStr); //返回隨機字符串則表示驗證通過 } else//消息 { //記錄發送的消息 string url = context.Request.Url.ToString(); context.Request.InputStream.Position = 0; StreamReader reader = new StreamReader(context.Request.InputStream); string sReqData = reader.ReadToEnd();//加密XML信息 string str=String.Format("URL\r\n{0}\r\nXML\r\n{1}",url,sReqData); WriteText(str); WXBizMsgCryptAPI apidata = new WXBizMsgCryptAPI(token, EncodingAESKey, CorpID, signature, timestamp, nonce); CustomMessageHandler messageHandler = new CustomMessageHandler(apidata,context.Request.InputStream,MaxMsgContextCount,MaxCommandContextCount); try { messageHandler.Execute(); WriteContent(messageHandler.Document); return; } catch (Exception ex) { WriteContent(""); } finally { } } } private void WriteText(string p) { CommonTools.WriteText(p); } public bool IsReusable { get { return false; } } private void WriteContent(string str) { HttpContext.Current.Response.Write(str); }
源代碼等稍后奉上!!!!如有疑問,請留言聯系
源碼下載地址:源碼下載