在準備工作中,我們已經完成準備工作,接下來就是進行開發啦,應該怎麼來開發呢??容我想想。。。我覺得我們可以直接讓用戶的消息發送到微信的消息,轉到我們自己的伺服器上面!!感覺好厲害的樣子1.首先寫 驗證程式啦,這第一步的工作呢,就是驗證數據是不是來源於微信端的,如果不是來自微信伺服器端的,那就安逸了。 ...
在準備工作中,我們已經完成準備工作,接下來就是進行開發啦,應該怎麼來開發呢??容我想想。。。我覺得我們可以直接讓用戶的消息發送到微信的消息,轉到我們自己的伺服器上面!!感覺好厲害的樣子
1.首先寫 驗證程式啦,這第一步的工作呢,就是驗證數據是不是來源於微信端的,如果不是來自微信伺服器端的,那就安逸了。。。,廢話不多說,直接上代碼
1.1這個是微信端頁面的配置
1.2 驗證微信數據來源
//獲取token
string Token = string.Format("{0}", ConfigurationManager.AppSettings["ToKen"]);//這個,簡單來說,就是我們自己的鑰匙,用來驗證的鑰匙,需要和微信端填寫的一模一樣,我這裡直接在Web.config裡面進行配置就行,見上圖
[HttpGet]
public ActionResult Index(string signature, string timestamp, string nonce, string echostr)//相關欄位信息我們可以直接上微信文檔瞭解,這裡就不一一列舉了
{
string[] ArrTmp = { Token, timestamp, nonce };
Array.Sort(ArrTmp); //字典排序
string tmpStr = string.Join("", ArrTmp);
tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");//這個就是SHA1加密
tmpStr = tmpStr.ToLower();
if (signature == tmpStr) // 如果從微信傳入的數據和我們的數據不一樣,那就表示傳入的數據不一定是從微信傳入的數據,就不能返回echostr參數
{
return Content(echostr);
}
else
{
ReturnInfo<SessionInfo> returnSessionInfo = GetSessionUserInfo();
if (returnSessionInfo.Code != 1)
{
//返回失敗信息到頁面
return RedirectToAction("Index", "Error"); ;
}
return View();
}
}
備註:在公司開發可能會遇到跨域問題,推薦使用工具ngnork,可實現內外網穿透
2.消息的獲取
2.1消息去重,使用msgid排重
static List<BaseMsg> _queue = new List<BaseMsg>();
//消息去重
if (_queue == null)
{
_queue = new List<BaseMsg>();
}
else if (_queue.Count >= 50)
{
_queue = _queue.Where(q => { return q.CreateTime.AddSeconds(20) > DateTime.Now; }).ToList();//保留20秒內未響應的消息
}
2.2消息的獲取
Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
byte[] requestByte = new byte[requestStream.Length];
requestStream.Read(requestByte, 0, (int)requestStream.Length);
string requestStr = Encoding.UTF8.GetString(requestByte);
//封裝請求類
XmlDocument requestDocXml = new XmlDocument();
requestDocXml.LoadXml(requestStr);
XmlElement rootElement = requestDocXml.DocumentElement;
XElement xdoc = XElement.Parse(requestStr);
var msgtype = xdoc.Element("MsgType").Value.ToUpper();
var FromUserName = xdoc.Element("FromUserName").Value;
var MsgId = xdoc.Element("MsgId").Value;
var CreateTime = xdoc.Element("CreateTime").Value;
if (msgtype != "event" && msgtype != "link" && msgtype != "location")
{
if (_queue.FirstOrDefault(m => { return m.MsgFlag == MsgId; }) == null)
{
_queue.Add(new BaseMsg
{
CreateTime = DateTime.Now,
FromUser = FromUserName,
MsgFlag = MsgId
});
}
else
{
return "";
}
}
else
{
return "";
}
接下來就是通過解析rootElement 來獲取對應欄位的消息了
如:string strFormUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
然後把數據保存至資料庫,整個消息接受和保存的數據流程就走完了