使用
目录 |
---|
在MVC中开发
Senparc.Weixin.MP.Sample中的关键代码说明(这是MVC项目,WebForms项目见Weixin.aspx)
/Controllers/WeixinController.cs
下面的Token需要和微信公众平台后台设置的Token同步,如果经常更换建议写入Web.config等配置文件(实际使用过程中两列建议使用数字+英文大小写改写Token,Token一旦被破解,微信请求将很容易被伪造!):
public readonly string Token = "weixin";
下面这个Action(Get)用于接收并返回微信后台Url的验证结果,无需改动。地址如:http://domain/Weixin或http://domain/Weixin/Index
/// <summary>
/// 微信后台验证地址(使用Get),微信后台的“接口配置信息”的Url填写如:http://weixin.senparc.com/weixin
/// </summary>
[HttpGet]
[ActionName("Index")]
public ActionResult Get(string signature, string timestamp, string nonce, string echostr)
{
if (CheckSignature.Check(signature, timestamp, nonce, Token))
{
return Content(echostr);//返回随机字符串则表示验证通过
}
else
{
return Content("failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, Token));
}
}
下面这个Action(Post)用于接收来自微信服务器的Post请求(通常由用户发起),这里的if必不可少,之前的Get只提供微信后台保存Url时的验证,每次Post必须重新验证,否则很容易伪造请求。
/// <summary>
/// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML
/// </summary>
[HttpPost]
[ActionName("Index")]
public ActionResult Post(string signature, string timestamp, string nonce, string echostr)
{
if (!CheckSignature.Check(signature, timestamp, nonce, Token))
{
return Content("参数错误!");
}
...
}
如何处理微信请求?
Senparc.Weixin.MP提供了2中处理请求的方式,传统方法及使用MessageHandler处理方法(推荐)。上面两个方法在wiki中已经有比较详细的说明,这里简单举例MessageHandler的处理方法。
MessageHandler的处理流程非常简单:
[HttpPost]
[ActionName("Index")]
public ActionResult Post(string signature, string timestamp, string nonce, string echostr)
{
if (!CheckSignature.Check(signature, timestamp, nonce, Token))
{
return Content("参数错误!");
}var messageHandler = new CustomMessageHandler(Request.InputStream);//接收消息
messageHandler.Execute();//执行微信处理过程
//return Content(messageHandler.ResponseDocument.ToString());//v0.7-
return new WeixinResult(messageHandler);//v0.8+ with MvcExtension
}
整个消息的接收、处理、返回分别只需要一行代码。
上述代码中的CustomMessageHandler是一个自定义的类,继承自Senparc.Weixin.MP.MessageHandler.cs。MessageHandler是一个抽象类,包含了执行各种不同请求类型的抽象方法(如文字,语音,位置、图片等等),我们只需要在自己创建的CustomMessageHandler中逐个实现这些方法就可以了。刚建好的CustomMessageHandler.cs如下:
using System;
using System.IO;
using Senparc.Weixin.MP.MessageHandlers;
using Senparc.Weixin.MP.Entities;namespace Senparc.Weixin.MP.Sample.CustomerMessageHandler
{
public class CustomMessageHandler : MessageHandler<MessageContext>
{
public CustomMessageHandler(Stream inputStream)
: base(inputStream)
{}
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
var responseMessage = this.CreateResponseMessage<ResponseMessageText>();//ResponseMessageText也可以是News等其他类型
responseMessage.Content = "这条消息来自DefaultResponseMessage。";
return responseMessage;
}public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
//...
}public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage)
{
//...
}//更多没有重写的OnXX方法,将默认返回DefaultResponseMessage中的结果。
....
}
}
其中OnTextRequest、OnVoiceRequest等分别对应了接收文字、语音等不同的请求类型。
比如我们需要对文字类型请求做出回应,只需要完善OnTextRequest方法:
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
//TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs
var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);//v0.3版本之前的非泛型方法仍然有效
responseMessage.Content =
string.Format(
"您刚才发送了文字信息:{0}",
requestMessage.Content);
return responseMessage;
}
这样CustomMessageHandler在执行messageHandler.Execute()的时候,如果发现请求信息的类型是文本,会自动调用以上代码,并返回代码中的responseMessage作为返回信息。responseMessage可以是IResponseMessageBase接口下的任何类型(包括文字、新闻、多媒体等格式)。
从v0.4.0开始,MessageHandler增加了对用户会话上下文的支持,用于解决服务器上无法使用Session管理用户会话的缺陷。详见:用户上下文WeixinContext和MessageContext