先申请微信公众号的受权,找到或配置几个关键的信息(开发者ID、开发者密码、IP白名单、令牌和消息加解密密钥等)。服务器
开发者ID:固定的;微信
开发者密码:本身扫一下就能够看到;async
IP白名单:设置本身配置服务器的地址;ide
服务器地址(URL):稍后详解;post
令牌:随便写,按规则;测试
消息加解密密钥:随便写,或者随机生成;spa
服务器地址(URL)应该怎么配置呢?图片上的配置的地址是:http://www.nidie.com.cn/wechat ,那么它对应的控制器应该是怎么样子的呢?code
在这里,我使用了第三方的包,须要经过 Nuget 来安装:blog
<package id="Senparc.Weixin" version="4.22.1" targetFramework="net471" /> <package id="Senparc.Weixin.MP" version="14.14.0" targetFramework="net471" /> <package id="Senparc.Weixin.MP.MVC" version="5.4.5" targetFramework="net471" />
接下来新建一个 WeChatController.cs:继承
using System.Threading.Tasks; using System.Web.Mvc; using Senparc.Weixin.MP; using Senparc.Weixin.MP.Entities.Request; using Senparc.Weixin.MP.MvcExtension; using Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers; using Wen.MvcDemo.Infrastructure.Configuration; namespace Wen.MvcDemo.Web.Controllers { /// <summary> /// 微信 /// </summary> public class WeChatController : Controller { #region private static field private static readonly string AppId = ApplicationSettingsFactory.GetApplicationSettings().WeChatAppId; private static readonly string EncodingAesKey = ApplicationSettingsFactory.GetApplicationSettings().WeChatEncodingAesKey; private static readonly string Token = ApplicationSettingsFactory.GetApplicationSettings().WeChatToken; #endregion private static field /// <summary> /// 微信后台验证地址 /// </summary> /// <param name="signature"></param> /// <param name="timestamp"></param> /// <param name="nonce"></param> /// <param name="echostr"></param> /// <returns></returns> [HttpGet] public ActionResult Index(string signature, string timestamp, string nonce, string echostr) { return Content(echostr); } /// <summary> /// 处理用户发送消息后 /// </summary> /// <param name="postModel"></param> /// <returns></returns> [HttpPost] public async Task<ActionResult> Index(PostModel postModel) { //校验签名 if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) return new WeixinResult("参数错误!"); postModel.AppId = AppId; postModel.EncodingAESKey = EncodingAesKey; postModel.Token = Token; //接收消息,自定义 MessageHandler,对微信请求进行处理 var messageHandler = new CustomMessageHandler(Request.InputStream, postModel); //执行微信处理过程 await messageHandler.ExecuteAsync(); //返回处理结果 return new FixWeixinBugWeixinResult(messageHandler); } } }
代码分析:
里面主要包含了三个静态字段和两个 Index 方法。
其中静态字段对应的就是基本配置信息里面对应的几个参数,日常都是写入配置文件中来进行读取。
其中一个标识特性为 HttpGet 的 Index 方法,它是用来经过服务器地址(URL)验证的,当你成功部署到你的服务器后,再点击提交认证就能够经过了。注意的是,须要将代码先提交到服务器,再进行提交确认。
可能你看到该方法好像只返回 return Content(echostr); 这么简单的代码感到质疑:这能行吗?“我”记得官方文档好像要调用很复杂的方法进行校验才行的!?
上图就是官方文档,可是我只关心经过配置提交认证,也就是我用红圈着色的部分,即原样返回 echostr 参数内容便可。
第二个是实现 Post 请求的 Index 方法,在这里我进行了签名校验(也就是上图文档的校验逻辑),由于使用了第三方库,咱们知道传哪些参数过去就能够了,签名经过后就是读取请求信息并进行后续处理的步骤了。
在上面的处理请求信息的代码中,我自定义了一个类 CustomMessageHandler 来处理消息。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using Senparc.Weixin.MP.AppStore; using Senparc.Weixin.MP.AppStore.Utility; using Senparc.Weixin.MP.Entities; using Senparc.Weixin.MP.Entities.Request; using Senparc.Weixin.MP.MessageHandlers; namespace Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers { /// <summary> /// 自定义消息处理 /// </summary> public class CustomMessageHandler : MessageHandler<CustomMessageContext> { public CustomMessageHandler(Stream inputStream, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(inputStream, postModel, maxRecordCount, developerInfo) { } public CustomMessageHandler(XDocument requestDocument, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestDocument, postModel, maxRecordCount, developerInfo) { } public CustomMessageHandler(RequestMessageBase requestMessageBase, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestMessageBase, postModel, maxRecordCount, developerInfo) { } /// <summary> /// 默认 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也能够是News等其余类型 responseMessage.Content = $"您好,目前使用的微信公众号仍处于开发阶段,现已接入了【图灵机器人】,您能够尝试和他(她)交流。"; return responseMessage; } } }
CustomMessageHandler 类继承了 MessageHandler 类,而后重写了 DefaultResponseMessage() 方法,返回固定的文本值。base.CreateResponseMessage<T>() 方法能够返回多种不一样类型的结果值,如:
ResponseMessageText - 对应文本消息 ResponseMessageNews - 对应图文消息 ResponseMessageMusic - 对应音乐消息 ResponseMessageXXX - 其余类型以此类推
上述方法只是一种默认的消息处理,咱们也能够专门针对不一样的请求类型作出不一样的回应,好比重写 OnTextRequest(),其它重载须要本身观察基类成员:
/// <summary> /// 文本请求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = $"您刚才发送的文字信息是:{requestMessage.Content}。"; //\r\n用于换行,requestMessage.Content即用户发过来的文字内容 return responseMessage; }
由于在继承 MessageHandler<T> 类的同时,我建立了一个 CustomMessageContext 自定义消息上下文的类,该类内容以下,并无包含其它方法,直接继承 MessageContext<IRequestMessageBase, IResponseMessageBase> 便可:
using Senparc.Weixin.Context; using Senparc.Weixin.MP.Entities; namespace Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers { /// <summary> /// 自定义消息上下文 /// </summary> public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase> { } }
这样,就完成了全部代码的编写,如今咱们再次把代码部署好以后就能够开始进行测试了。
由于我除了部署本身的站点以外,还接入了【图灵机器人】回复,因此你看到了两条信息。