專案GitHub地址:https://github.com/Andyahui/xgyxsh_WeiXin
一:微信XML的POST請求處理
一:微信XML的POST請求處理時可以到底,且是得到了對應的處理,以下是我們透過瀏覽器我們配置的URL瀏覽到的。
我們可以發現在get請求中設定的回傳值在這裡出現了,說明我們的測試是成功的。下面我們要設定POST請求對應的Action。
注意:由於我們微信和網站伺服器的每一次互動都是透過POST請求來得到自己想要的東西,我們就必須為傳輸進行加密。
/// <summary> /// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。 /// PS:此方法为简化方法,效果与OldPost一致。 /// v0.8之后的版本可以结合Senparc.Weixin.MP.MvcExtension扩展包,使用WeixinResult,见MiniPost方法。 /// </summary> [HttpPost] [ActionName("Index")] public ActionResult Post(PostModel postModel) { postModel.Token = Token; // postModel.EncodingAESKey = ""; //根据自己后台的设置保持一致 // postModel.AppId = AppId; //根据自己后台的设置保持一致 //验证数字签名 if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { //??? 这里有问题,要是不注释的话,就会在这里出错,也就是数字签名有问题。 //return Content("参数错误!"); } // 1:自定义MessageHandler,对微信请求的详细判断操作都在这里面。 实例化了一个类 var messageHandler = new CustomMessageHandle(Request.InputStream, postModel); //接收消息 // 2:执行微信处理过程----执行完这里之后ResponseMessage才会有值。 messageHandler.Execute(); // 3:return new FixWeixinBugWeixinResult(messageHandler); 这个有换行的问题。 //return new FixWeixinBugWeixinResult(messageHandler.ToString()); // 3:注意第三个----为了解决官方微信5.0软件换行bug暂时添加的方法,平时用下面一个方法即可 return new WeixinResult(messageHandler); //v0.8+ }
我們可以清楚的看到上面的每一行的意思,這裡我有個疑問,驗證數字簽名的里面要是不註釋if判斷裡面的就直接顯示「參數錯誤」不會繼續執行下面的操作,但是官網部落格裡面沒有註釋,不知道為什麼? ? (求大神解答。)
上面主要有三步:
先是實例化了CustomMessageHandle對象,並且傳遞了對應的參數,透過對應的CTOR進行了初始化,接著調用它的初始化,接著調用它的Execute()方法,最後透過實例化WeixinResult來傳回對應的CustomMessageHandle對象,此時物件中就包含了我們網站後台的邏輯處理方法。
這就是我們POST請求對於的處理,每一次微信伺服器轉發的信息 這就是我們POST請求對於的處理,每一次微信服務器轉發的信息
xml ,我們進行處理。二:了解MessageHandler
要完成微信開發,SDK中關鍵類就需要了解,下面就簡單說下MessageHandler; ,進行對應的處理。也可以進行邏輯判斷,說白了就是我們所有的業務邏輯都是在這個類別下面進行的。 。
這是一個抽象類,我們需要透過繼承重新實現它。下面是具體的實作。 《這裡是對應官方的解釋WiKi》。 namespace XGY_WeiXin.WeiXinHelper
{
public class CustomMessageHandle : MessageHandler<CustomMessageContext>
{
//PostModel:表示的都是从微信服务器里面得到的值,时间戳,字符串等。(WeiXinController中使用过)
//构造函数的inputStream用于接收来自微信服务器的请求流(如果需要在外部处理,这里也可以传入XDocument)。
public CustomMessageHandle(Stream inputSrream,PostModel postModel):base(inputSrream,postModel)
{
}
/// <summary>
/// 必须实现抽象的类------作用:用于放回一条信息,当没有对应类型的微信消息没有被代码处理,那么默认会执行返回这里的结果。
/// </summary>
/// <param name="requestMessage">请求消息</param>
/// <returns></returns>
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
//CreateResponseMessage<T> 这里是创建一个放回的对象,代表不同的类型,
var responseMessage = base.CreateResponseMessage<ResponseMessageText>();//ResponseMessageText可以更换为别的类型
responseMessage.Content = "这条消息来自DefaultResponseMessage。";
return responseMessage;
}
/// <summary>
///1: 处理用户发送过来的文字消息。重写OnTextRequest方法。
/// --------(总结:)方法里面可以自由发挥,读取DB,判断关键字,甚至返回不同的ResponseMessageXX类型(只要最终的类型都是在IResponseMessageBase接口下的即可)。
/// </summary>
/// <param name="requestMessage">请求消息</param>
/// <returns></returns>
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
//CreateResponseMessage<类型>根据当前的RequestMessage创建指定类型的ResponseMessage;创建相应消息.
var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName + "。\r\t您发送了文字信息:" +
requestMessage.Content;
return responseMessage;
}
}
}
WiKi)。 接著下面是個CTOR,主要是實例化的時候使用
三:自訂上下文CustomMessageContext
下面是自定义上下文类CustomMessageContext,主要是继承自MessageContextfc3c6664750ac75e4617a1dbf32e095a来实现对于的功能。
/// <summary> /// 自定义的上下文类---->处理单个用户的对话状态。 /// </summary> public class CustomMessageContext : MessageContext<IRequestMessageBase,IResponseMessageBase> { public CustomMessageContext() { base.MessageContextRemoved+=CustomMessageContext_MessageContextRemoved; } /// <summary> /// 当上下文过期,被移除的时候触发的时间 /// </summary> private void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e) { /* 注意,这个事件不是实时触发的(当然你也可以专门写一个线程监控) * 为了提高效率,根据WeixinContext中的算法,这里的过期消息会在过期后下一条请求执行之前被清除 */ var messageContext = e.MessageContext as CustomMessageContext; if (messageContext==null) { //如果是正常的调用,messageContext不会为null return ; } //TODO:这里根据需要执行消息过期时候的逻辑,下面的代码仅供参考 //Log.InfoFormat("{0}的消息上下文已过期",e.OpenId); //api.SendMessage(e.OpenId, "由于长时间未搭理客服,您的客服状态已退出!"); } }
解释参考官方给的解释,版本升级了(WiKi),我觉得这里以后还是会做大文章的。
四:微信测试号效果展示
此时我们大体的底层框架就搭建成功了,我们发布部署到服务器上面就可以看到文本处理的响应了。
这是微信的二维码可以关注下,可以实现简单的互动。
更多微信开发系列----02:实现POST请求响应 相关文章请关注PHP中文网!