本文實例講述了.net開發微信公眾平台的方法。分享給大家供大家參考。具體實現方法如下:
一、說明:
公眾平台信息接口為開發者提供了一種新的消息處理方式,只有申請成為開發者後,你才能使用公眾平台的開發功能,在這裡你需要填寫一個URL和一個Token,這兩項信息也需要你擁有自己的服務器(外網服務器)資源,其中的Token可由開發者任意填寫,URL即是接口配置信息的鏈接地址,在本文中我采用的是創建一個簡易網站的方式,在其中的一個頁面的後台程序中配置相關的接口信息,然後發布到外網服務器上,最後可以訪問到這個頁面的鏈接地址即是這裡應該填寫的URL。
二、接口配置過程:
1.網址接入-校驗簽名:
復制代碼 代碼如下:const string Token = "aka";//定義一個局部變量不可以被修改,這裡定義的變量要與接口配置信息中填寫的Token一致
protected void Page_Load(object sender, EventArgs e)
{
string postStr = "";
Valid();//校驗簽名,當填入的信息提交之後頁面有提示“你已成功成為公眾平台開發者,可以使用公眾平台的開發功能”這個的時候,接下來你就需要注釋掉這個校驗的方法,使得後面的消息回復得以正常運作
if (Request.HttpMethod.ToLower() == "post")//當普通微信用戶向公眾賬號發消息時,微信服務器將POST該消息到填寫的URL上
{
postStr = PostInput();
if (string.IsNullOrEmpty(postStr) == false)
{
//WriteLog(postStr,Server);//計入日記
ResponseMsg(postStr);
}
}
}
private void Valid()
{
string echoStr = Request.QueryString["echoStr"].ToString();
if (CheckSignature())
{
if (!string.IsNullOrEmpty(echoStr))
{
Response.Write(echoStr);
Response.End();
}
}
}
復制代碼 代碼如下:/// <summary>
/// 驗證微信簽名
/// </summary>
/// <returns></returns>
private bool CheckSignature()
{
string signature = Request.QueryString["signature"].ToString();
string timestamp = Request.QueryString["timestamp"].ToString();
string nonce = Request.QueryString["nonce"].ToString();
string[] ArrTmp = { Token, timestamp, nonce };
Array.Sort(ArrTmp);//字典排序
string tmpStr = string.Join("", ArrTmp);
tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");//對該字符串進行sha1加密
tmpStr = tmpStr.ToLower();//對字符串中的字母部分進行小寫轉換,非字母字符不作處理
//WriteLog(tmpStr, Server);//計入日志
if (tmpStr == signature)//開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信。開發者通過檢驗signature對請求進行校驗,若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則接入生效,否則接入失敗
{
return true;
}
else
return false;
}
/// <summary>
/// 獲取post返回來的數據
/// </summary>
/// <returns></returns>
private string PostInput()
{
Stream s = System.Web.HttpContext.Current.Request.InputStream;
byte[] b = new byte[s.Length];
s.Read(b, 0, (int)s.Length);
return Encoding.UTF8.GetString(b);
}
/// <summary>
///返回微信信息結果
/// </summary>
/// <param name="weixinXML"></param>
private void ResponseMsg(string weixinXML)
{
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(weixinXML);//讀取XML字符串
XmlElement rootElement = doc.DocumentElement;
XmlNode MsgType = rootElement.SelectSingleNode("MsgType");//獲取字符串中的消息類型
string resxml = "";
if (MsgType.InnerText == "text")//如果消息類型為文本消息
{
var model = new
{
ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,
FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,
CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,
MsgType = MsgType.InnerText,
Content = rootElement.SelectSingleNode("Content").InnerText,
MsgId = rootElement.SelectSingleNode("MsgId").InnerText
};
resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";
if (!string.IsNullOrEmpty(model.Content))//如果接收到消息
{
if (model.Content.Contains(" 你好") || model.Content.Contains(" 好") || model.Content.Contains("hi") || model.Content.Contains("hello"))// 你好
{
resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好,有事請留言,偶會及時回復你的。]]></Content><FuncFlag>0</FuncFlag></xml>";
}
}
else//沒有接收到消息
{
resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[親,感謝您對我的關注,有事請留言。]]></Content><FuncFlag>0</FuncFlag></xml>";
}
Response.Write(resxml);
}
if (MsgType.InnerText == "image")//如果消息類型為圖片消息
{
var model = new
{
ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,
FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,
CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,
MsgType = MsgType.InnerText,
PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText,
MsgId = rootElement.SelectSingleNode("MsgId").InnerText
};
resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>1</ArticleCount><Articles><item><Title><![CDATA[歡迎您的光臨!]]></Title><Description><![CDATA[非常感謝您的關注!]]></Description><PicUrl><![CDATA[http://...jpg]]></PicUrl><Url><![CDATA[http://www.baidu.com/]]></Url></item></Articles><FuncFlag>0</FuncFlag></xml>";
Response.Write(resxml);
}
else//如果是其余的消息類型
{
var model = new
{
ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,
FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,
CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,
};
resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[親,感謝您對我的關注,有事請留言,我會及時回復你的哦。]]></Content><FuncFlag>0</FuncFlag></xml>";
Response.Write(resxml);
}
}
catch (Exception ex)
{
throw ex;
}
Response.End();
}
/// <summary>
/// datetime轉換成unixtime
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
private int ConvertDateTimeInt(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(time - startTime).TotalSeconds;
}
/// <summary>
/// 寫日志(用於跟蹤),可以將想打印出的內容計入一個文本文件裡面,便於測試
/// </summary>
public static void WriteLog(string strMemo, HttpServerUtility server)
{
string filename = server.MapPath("/logs/log.txt");//在網站項目中建立一個文件夾命名logs(然後在文件夾中隨便建立一個web頁面文件,避免網站在發布到服務器之後看不到預定文件)
if (!Directory.Exists(server.MapPath("//logs//")))
Directory.CreateDirectory("//logs//");
StreamWriter sr = null;
try
{
if (!File.Exists(filename))
{
sr = File.CreateText(filename);
}
else
{
sr = File.AppendText(filename);
}
sr.WriteLine(strMemo);
}
catch
{
}
finally
{
if (sr != null)
sr.Close();
}
}
希望本文所述對大家的.net程序設計有所幫助。