参考:
Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler
Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题
WeiXinApi.Application新建Handler文件夹,并新建文件CustomMessageHandler
继承 MessageHandler<DefaultMpMessageContext>并实现抽象类
namespace WeiXinApi.Application.Handler { public class CustomMessageHandler : MessageHandler<DefaultMpMessageContext> { private string appId = Config.SenparcWeixinSetting.WeixinAppId; private string appSecret = Config.SenparcWeixinSetting.WeixinAppSecret; public CustomMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0, bool onlyAllowEncryptMessage = false, Senparc.NeuChar.App.AppStore.DeveloperInfo developerInfo = null, IServiceProvider serviceProvider = null) : base(inputStream, postModel, maxRecordCount, onlyAllowEncryptMessage, developerInfo, serviceProvider) { //这里设置仅用于测试,实际开发可以在外部更全局的地方设置, //比如MessageHandler<MessageContext>.GlobalGlobalMessageContext.ExpireMinutes = 3。 GlobalMessageContext.ExpireMinutes = 3; OnlyAllowEncryptMessage = false;//是否只允许接收加密消息,默认为 false if (!string.IsNullOrEmpty(postModel.AppId)) { appId = postModel.AppId;//通过第三方开放平台发送过来的请求 } //在指定条件下,不使用消息去重 base.OmitRepeatedMessageFunc = requestMessage => { var textRequestMessage = requestMessage as RequestMessageText; if (textRequestMessage != null && textRequestMessage.Content == "容错") { return false; } return true; }; } public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型 responseMessage.Content = "这条消息来自DefaultResponseMessage。"; return responseMessage; } } }
WeiXinService构造函数里注入IHttpContextAccessor
public WeiXinService(IHttpContextAccessor httpContextAccessor) { this._httpContextAccessor = httpContextAccessor; }
WeiXinService里新建一个回复接口,并发布到云服务器,通过附加到进程调试
[HttpPost("/wx")] public async Task<ContentResult> Receive([FromQuery] PostModel postModel) { ContentResult content = new ContentResult(); Console.WriteLine("收到消息"); //测试时候忽略验证 //if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) //{ // content.Content = "参数错误!"; // return content; //} postModel.Token = Token; postModel.EncodingAESKey = EncodingAESKey;//根据自己后台的设置保持一致 postModel.AppId = AppId;//根据自己后台的设置保持一致 //v4.2.2之后的版本,可以设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制(实际最大限制 99999) //注意:如果使用分布式缓存,不建议此值设置过大,如果需要储存历史信息,请使用数据库储存 //自定义MessageHandler,对微信请求的详细判断操作都在这里面。 try { var maxRecordCount = 10; var messageHandler = new CustomMessageHandler(_httpContextAccessor.HttpContext.Request.Body, postModel, maxRecordCount); messageHandler.SaveRequestMessageLog();//记录 Request 日志(可选) var ct = new CancellationToken(); await messageHandler.ExecuteAsync(ct);//执行微信处理过程(关键) messageHandler.SaveResponseMessageLog();//记录 Response 日志(可选) var result = messageHandler.ResponseDocument.ToString(); content.Content = result; } catch (Exception ex) { Console.WriteLine(ex.Message); content.Content = ""; } return content; }
通过消息调试接口,发送一条文本消息试试
这时候我们发现报错了
百度了下这个错误,发现我复制胜派demo里的代码没有复制全,只需要在ConfigureServices里加入这段代码即可
//如果部署在linux系统上,需要加上下面的配置: services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true); //如果部署在IIS上,需要加上下面的配置: //services.Configure<IISServerOptions>(options => options.AllowSynchronousIO = true);
重新请求接口,发现成功返回xml格式的字符串
用真机测试一下,没毛病
https://gitee.com/huguodong520/weixinapi/tree/%E6%8E%A5%E5%85%A5%E5%85%AC%E4%BC%97%E5%8F%B7/