进入微信公众平台网站,这里用测试账号进行演示
点击开发者中心>公众平台测试账号>接口配置信息
在这里输入url和token
测试通过就可以使用填写的url作为服务端来操作了。
下面主要介绍服务端代码
首页代码:
/// <summary>
/// IndexHander 的摘要说明
/// </summary>
public class IndexHander : IHttpHandler
{
private static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//http://blueummser-001-site1.site4future.com/IndexHander.ashx
public void ProcessRequest(HttpContext context)
{
Log.Debug("\ncomein");
//由微信服务接收请求,具体处理请求
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();
Log.Debug("responseMsg:" + responseMsg);
Log.Debug("comeout\n");
}
public bool IsReusable
{
get
{
return false;
}
}
Services代码:注:除去token验证之外,所有的请求方式都为post方式,,微信服务器发来的是一串xml字符串,这里将其转换为xml文档
public class WeiXinService
{
private static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string TOKEN = "bluesummer";
private HttpRequest Request;
public WeiXinService(HttpRequest httpRequest)
{
Request = httpRequest;
}
public string Response()
{
string method = Request.HttpMethod.ToUpper();
Log.Debug("method:" + method);
//验证签名
if (method == "GET")
{
bool checkResult = CheckSignature();
Log.Debug("checkResult:" + checkResult);
if (checkResult)
return Request.QueryString["echostr"];
else
return "error";
}
//处理消息
if (method == "POST")
return ResponseMsg();
else
return "无法处理";
}
/// <summary>
/// 处理请求
/// </summary>
/// <returns></returns>
private string ResponseMsg()
{
string requestXml = Common.ReadRequest(this.Request);
Log.Debug("requestXml:" + requestXml);
IHandler handler = HanderFactory.CreateHander(Common.ConvertXmlStr(requestXml));
if (handler != null)
{
return handler.HandleRequest();
}
return string.Empty;
}
/// <summary>
/// 检查签名
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private bool CheckSignature()
{
string signature = this.Request.QueryString["signature"];
string timestamp = this.Request.QueryString["timestamp"];
string nonce = this.Request.QueryString["nonce"];
Log.Debug("signature:" + signature);
Log.Debug("timestamp:" + timestamp);
Log.Debug("nonce:" + nonce);
string[] ArrTmp = { TOKEN, timestamp, nonce };
Array.Sort(ArrTmp); //字典排序
string tmpStr = string.Join("", ArrTmp);
tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
tmpStr = tmpStr.ToLower();
if (tmpStr == signature)
{
return true;
}
else
{
return false;
}
}
/// <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();
}
}
HandlerFactory:主要负责事件和普通文本两种请求的处理
public class HanderFactory
{
private static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static IHandler CreateHander(XmlDocument xmldoc)
{
XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
Log.Debug("MsgType:" + MsgType.InnerText);
if (MsgType != null)
{
switch (MsgType.InnerText.ToLower())
{
case "event":
return new EventHandler(xmldoc);//事件处理
case "text":
return new TextHandler(xmldoc);;//接受文本消息处理
default:
break;
}
}
return null;
}
}
附上texthandler代码:
public class TextHandler : IHandler
{
private static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// 请求的xml
/// </summary>
private XmlDocument RequestXml { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="requestXml"></param>
public TextHandler(XmlDocument xmlDoc)
{
this.RequestXml = xmlDoc;
}
/// <summary>
/// 处理请求
/// </summary>
/// <returns></returns>
public string HandleRequest()
{
Log.Debug("TextHander:HandleRequest");
string response = string.Empty;
try
{
TextMessage tm = TextMessage.LoadFromXml(RequestXml);
IReplay replaydemo = new IReplay()
{
ToUserName = tm.FromUserName,
FromUserName = tm.ToUserName,
CreateTime = Common.GetNowTime()
};
IReplay replay = new TextReplay(replaydemo, "文字格式错误"); ;
Log.Debug("TextHander:new TextMessage()ok");
switch (tm.Content)
{
case "你好":
replay = new TextReplay(replaydemo, "你好");
break;
case "图文列表":
List<NewsItem> list = new List<NewsItem>();
NewsItem item = new NewsItem("title", "descrip", "http://b.hiphotos.baidu.com/image/pic/item/9f510fb30f2442a7f0a17475d243ad4bd01302b6.jpg", "http://www.soso.com/");
NewsItem item2 = new NewsItem("title2", "descrip2", "http://d.hiphotos.baidu.com/image/pic/item/f7246b600c33874438f06f7d530fd9f9d72aa0fe.jpg", "http://www.soso.com/");
list.Add(item); list.Add(item2);
replay = new NewsMainReplay(replaydemo, "2", list);
break;
}
Log.Debug("TextHander:new TextReplay()ok");
response = replay.GetReplayXml();
Log.Debug("response:" + response);
}
catch (Exception e)
{
Log.Debug("Exception:" + e.Message);
}
return response;
}
}
回复的文字格式同样要以xml格式回复
public class TextReplay : IReplay
{
private static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public string Content { get; set; }
public TextReplay(IReplay replay, string Content)
{
this.ToUserName = replay.ToUserName;
this.FromUserName = replay.FromUserName;
this.CreateTime = replay.CreateTime;
this.Content = Content;
}
public override string GetReplayXml()
{
Log.Debug("come TextReplay GetReplayXml()");
string xmlStr = @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml>";
return string.Format(xmlStr, ToUserName, FromUserName, CreateTime, Content);
}
}