WeiXinMPSDK 微信小程序 MessageHandler 完全指南:自定义消息处理、中间件与 Controller 两种承载方式实战
发布时间:2026/9/25 7:15:31来源:尧图网络
后端即时通讯金融科技【免费下载链接】WeiXinMPSDK微信全平台 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 WeChat SDK for C#.项目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK点击查看免费下载导读本文以 Senparc.WeixinWeiXinMPSDK开源仓库中 docs/en/guide/wxopen/messagehandler.md 为骨架系统讲解微信小程序WxOpen客服消息体系的MessageHandler机制。你将掌握如何继承WxOpenMessageHandlerTMC编写自定义消息处理器、如何区分必须重写与可选重写的方法、如何通过中间件方式推荐一行代码注册与Controller 方式精细化控制每一步执行两种途径把消息处理器暴露给微信服务器并深入理解其背后的消息路由、上下文、消息去重与签名校验实现原理最终能够在自己的小程序后端中快速落地一套可运行、可扩展的客服消息处理方案。一、MessageHandler 是什么小程序客服消息的统一入口微信小程序与用户之间的客服对话窗口消息以及微信服务器主动推送的各种事件如用户进入客服会话、用户发送文字/图片/小程序卡片等都需要在开发者服务器上有一个统一、稳定的接收与响应入口。在 Senparc.Weixin SDK 中这个入口就是MessageHandler。MessageHandler用于处理小程序客服对话窗口的消息以及其他微信服务器的推送信息。SDK 已经为开发者准备好了所有需要的基础功能——包括消息的接收解析、签名校验、消息去重、上下文会话管理、响应消息的构造与序列化等——开发者只需要创建一个自定义的子类重写与业务相关的处理方法即可完成绝大多数业务场景。从类继承关系看见 WxOpenMessageHandler.csSDK 提供的是一个泛型抽象基类public abstract partial class WxOpenMessageHandlerTMC : MessageHandlerTMC, IRequestMessageBase, IResponseMessageBase where TMC : class, IMessageContextIRequestMessageBase, IResponseMessageBase, new()其中泛型参数TMC是消息上下文MessageContext类型用于维护单个用户的会话状态。开发者只需要继承这个基类并指定自己的上下文类型即可。二、自定义 MessageHandlerCustomWxOpenMessageHandler 实战2.1 两个核心文件当前示例中自定义的 MessageHandler 命名为CustomWxOpenMessageHandler位于示例项目的MessageHandlers/目录下Samples/WxOpen/Senparc.Weixin.Sample.WxOpen/MessageHandlers/包含两个文件文件作用CustomWxOpenMessageHandler.cs自定义 MessageHandler消息处理核心逻辑CustomWxOpenMessageContext.cs自定义重写DefaultWxOpenMessageContext上下文可选类定义与基类的对应关系CustomWxOpenMessageHandler.cspublic partial class CustomWxOpenMessageHandler : WxOpenMessageHandlerCustomWxOpenMessageContext注意这里用到的上下文类型是CustomWxOpenMessageContext它继承自 SDK 内置的DefaultWxOpenMessageContextCustomWxOpenMessageContext.cs。上下文MessageContext保存着某个用户OpenId在会话期间的历史消息列表与自定义存储数据是后续实现上下文消息记录回显等功能的基础。2.2 必须重写与可选重写的方法在CustomWxOpenMessageHandler.cs中演示的所有重写方法中只有DefaultResponseMessageAsync()是必须重写的其他所有OnXxxRequestAsync()方法都是可选的。当用户发送的消息类型找不到对应的重写方法时框架会自动调用DefaultResponseMessageAsync()作为兜底响应。对应到 SDK 基类源码OnXxxRequestAsync系列方法均为virtual虚方法且默认实现会回落fallback到默认响应见 WxOpenMessageHandler.Message.cspublic async virtual TaskIResponseMessageBase OnImageRequestAsync(RequestMessageImage requestMessage) { return await DefaultAsyncMethod(requestMessage, () OnImageRequest(requestMessage)).ConfigureAwait(false); } public async virtual TaskIResponseMessageBase OnTextRequestAsync(RequestMessageText requestMessage) { return await DefaultAsyncMethod(requestMessage, () OnTextRequest(requestMessage)).ConfigureAwait(false); } public async virtual TaskIResponseMessageBase OnMiniProgramPageRequestAsync(RequestMessageMiniProgramPage requestMessage) { return await DefaultResponseMessageAsync(requestMessage).ConfigureAwait(false); }而消息路由分发逻辑在 WxOpenMessageHandler.cs 中按消息类型调用对应的处理方法例如await OnTextRequestAsync(RequestMessage as RequestMessageText); await OnImageRequestAsync(RequestMessage as RequestMessageImage); ResponseMessage await OnMiniProgramPageRequestAsync(RequestMessage as RequestMessageMiniProgramPage);也就是说你重写了哪个类型的处理方法该类型的消息就走你的逻辑未重写的类型统一落到DefaultResponseMessageAsync()。版本提示基类中旧的同步方法OnTextRequest、OnImageRequest已被标记为[Obsolete]见 WxOpenMessageHandler.Message.cs官方推荐全面使用异步方法OnXxxRequestAsync。2.3 一个可直接运行的完整示例以下是示例项目中CustomWxOpenMessageHandler.cs的完整核心实现有精简注释覆盖了文字、图片、进入客服事件、小程序卡片等常见场景可以直接对照学习public partial class CustomWxOpenMessageHandler : WxOpenMessageHandlerCustomWxOpenMessageContext { private string appId Config.SenparcWeixinSetting.WxOpenAppId; private string appSecret Config.SenparcWeixinSetting.WxOpenAppSecret; /// summary /// 为中间件提供生成当前类的委托中间件方式必需 /// /summary public static FuncStream, PostModel, int, IServiceProvider, CustomWxOpenMessageHandler GenerateMessageHandler (stream, postModel, maxRecordCount, serviceProvider) new CustomWxOpenMessageHandler(stream, postModel, maxRecordCount, serviceProvider); public CustomWxOpenMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount 0, IServiceProvider serviceProvider null) : base(inputStream, postModel, maxRecordCount, serviceProvider: serviceProvider) { // 设置消息上下文过期时间单位分钟 GlobalMessageContext.ExpireMinutes 3; 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 async Task OnExecutingAsync(CancellationToken cancellationToken) { var currentMessageContext await base.GetCurrentMessageContext(); if (currentMessageContext.StorageData null || (currentMessageContext.StorageData is int)) { currentMessageContext.StorageData 0; } await base.OnExecutingAsync(cancellationToken); } // 执行后钩子累加计数 public override async Task OnExecutedAsync(CancellationToken cancellationToken) { await base.OnExecutedAsync(cancellationToken); try { var currentMessageContext await base.GetCurrentMessageContext(); currentMessageContext.StorageData ((int)currentMessageContext.StorageData) 1; } catch (Exception ex) { Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog(小程序 OnExecutedAsync 常规跟踪开发者请忽略, ex.ToString()); } } /// summary /// 处理文字请求 /// /summary public override async TaskIResponseMessageBase OnTextRequestAsync(RequestMessageText requestMessage) { var contentUpper requestMessage.Content.ToUpper(); if (contentUpper LINK) { // 发送图文链接客服消息 await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendLinkAsync(appId, OpenId, 欢迎使用 Senparc.Weixin SDK, 感谢大家的支持\r\n\r\n盛派永远在你身边, https://weixin.senparc.com, https://sdk.weixin.senparc.com/images/book-cover-front-small-3d-transparent.png); } else if (contentUpper CARD) { // 上传封面临时素材后发送小程序卡片客服消息 var uploadResult await MP.AdvancedAPIs.MediaApi.UploadTemporaryMediaAsync(appId, UploadMediaFileType.image, ServerUtility.ContentRootMapPath(~/Images/Logo.thumb.jpg)); await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendMiniProgramPageAsync(appId, OpenId, 欢迎使用 Senparc.Weixin SDK, pages/websocket/websocket, uploadResult.media_id); } else if (contentUpper 客服) { // 进入多客服会话 await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, 您即将进入客服); var responseMessage base.CreateResponseMessageResponseMessageTransfer_Customer_Service(); return responseMessage; } else { // 回显用户输入并展示历史消息记录来自 MessageContext var result new StringBuilder(); result.AppendFormat(您刚才发送了文字信息{0}\r\n\r\n, requestMessage.Content); var messageContext await GetCurrentMessageContext().ConfigureAwait(false); if (messageContext.RequestMessages.Count 1) { result.AppendFormat(您刚才还发送了如下消息{0}/{1}\r\n, messageContext.RequestMessages.Count, messageContext.StorageData); for (int i messageContext.RequestMessages.Count - 2; i 0; i--) { // ... 遍历历史消息拼装时间、消息类型与内容 } result.AppendLine(\r\n); } // 处理微信换行符识别问题 var msg result.ToString().Replace(\r\n, \n); // 发送客服消息 await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg); } return new SuccessResponseMessage(); } // 处理图片请求回显图片 public override async TaskIResponseMessageBase OnImageRequestAsync(RequestMessageImage requestMessage) { await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, 刚才您发送了这张图片); await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendImageAsync(appId, OpenId, requestMessage.MediaId); return await DefaultResponseMessageAsync(requestMessage); } // 用户进入客服会话事件 public override async TaskIResponseMessageBase OnEvent_UserEnterTempSessionRequestAsync(RequestMessageEvent_UserEnterTempSession requestMessage) { var msg 欢迎您这条消息来自 Senparc.Weixin 进入客服事件。 ... ; await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg); return await DefaultResponseMessageAsync(requestMessage); } // 小程序卡片消息 public override async TaskIResponseMessageBase OnMiniProgramPageRequestAsync(RequestMessageMiniProgramPage requestMessage) { var msg $您从某个小程序页面来到客服并且发送了小程序卡片。\r\nTitle{requestMessage.Title}\r\nAppId{requestMessage.AppId.Substring(1,5)}...\r\nPagePath{requestMessage.PagePath}; await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg); await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendImageAsync(appId, OpenId, requestMessage.ThumbMediaId); return await DefaultResponseMessageAsync(requestMessage); } // 兜底响应所有未处理的消息默认返回这里 public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { return new SuccessResponseMessage(); } public override async TaskIResponseMessageBase DefaultResponseMessageAsync(IRequestMessageBase requestMessage) { return await Task.FromResult(new SuccessResponseMessage()); } }关键设计点说明GenerateMessageHandler静态委托这是中间件方式能够直接使用当前类的桥梁。中间件需要一种无参构造消息处理器实例的能力因此示例类上定义了与中间件签名完全一致的静态委托FuncStream, PostModel, int, IServiceProvider, CustomWxOpenMessageHandler中间件注册时直接传入该委托即可。客服消息主动推送与被动响应的区别小程序客服体系下多数业务回复通过客服消息接口CustomApi.SendTextAsync等主动发送给用户而不是像公众号那样返回 XML。示例代码最后统一return new SuccessResponseMessage()表示已成功接收注释中特别说明在小程序中像公众号那样回复 XML 是无效的。这是小程序与公众号 MessageHandler 最核心的差异之一。上下文历史消息回显利用GetCurrentMessageContext()获取当前用户的MessageContext读取RequestMessages历史列表与StorageData自定义数据即可实现您刚才还发送了如下消息这类多轮会话体验。消息去重开关构造函数中通过OmitRepeatedMessageFunc可以精细控制哪些消息不做去重示例中用户输入容错时不去重这与 Controller 方式中的OmitRepeatedMessage true开关配合使用详见后文。OnExecutingAsync/OnExecutedAsync钩子分别在消息处理前、处理后执行适合做统一的埋点、日志、上下文数据维护示例中用它完成了StorageData的初始化与计数累加。2.4 可选的自定义上下文CustomWxOpenMessageContextCustomWxOpenMessageContext继承自DefaultWxOpenMessageContext核心价值在于订阅上下文过期移除事件CustomWxOpenMessageContext.cspublic class CustomWxOpenMessageContext : DefaultWxOpenMessageContext { public CustomWxOpenMessageContext() { base.MessageContextRemoved CustomMessageContext_MessageContextRemoved; } void CustomMessageContext_MessageContextRemoved(object sender, WeixinContextRemovedEventArgsIRequestMessageBase, IResponseMessageBase e) { // 注意这个事件不是实时触发的。 // 为了提高效率根据 WeixinContext 中的算法过期消息会在过期后、下一条请求执行之前被清除。 var messageContext e.MessageContext as CustomWxOpenMessageContext; if (messageContext null) return; // TODO: 这里根据需要执行消息过期时候的逻辑 // Log.InfoFormat({0}的消息上下文已过期, e.OpenId); // api.SendMessage(e.OpenId, 由于长时间未搭理客服您的客服状态已退出); } }典型用途包括会话超时后向用户发送长时间未回复客服会话已退出的提示或清理与该会话关联的临时业务数据。上下文过期时间由GlobalMessageContext.ExpireMinutes控制示例中设为 3 分钟。三、两种承载方式中间件与 ControllerMessageHandler 有两种承载方式使其可以被外部微信服务器通过 URL 访问到分别是中间件方式推荐和Controller 方式。两种方式所使用的CustomWxOpenMessageHandler是通用的因此可以随时切换和共存——甚至可以同时注册两个不同路径分别走两种方式。3.1 方式一中间件承载推荐最简化中间件方式是推荐的方式也是最简化的方式无需创建任何新文件只需在Program.cs文件所有 Senparc.Weixin 注册代码执行后的下方引入中间件完整示例见 Program.csapp.UseMessageHandlerForWxOpen(/WxOpenAsync, CustomWxOpenMessageHandler.GenerateMessageHandler, options { options.AccountSettingFunc context Senparc.Weixin.Config.SenparcWeixinSetting; });注册完成后即可通过 URL域名/WxOpenAsync访问 MessageHandler将该地址设置为小程序后台的消息推送 URL服务器域名 消息推送配置即可。在示例项目中中间件注册还演示了两个进阶选项Program.csapp.UseMessageHandlerForWxOpen(/WxOpenAsync, CustomWxOpenMessageHandler.GenerateMessageHandler, options { // 获取默认微信配置 var weixinSetting Senparc.Weixin.Config.SenparcWeixinSetting; // [必填] 指定微信配置 options.AccountSettingFunc context weixinSetting; // [可选] 设置文本返回长度限制如需超长消息可通过客服接口分段回复 options.TextResponseLimitOptions new TextResponseLimitOptions(2048, weixinSetting.WxOpenAppId); });其中options.AccountSettingFunc为必填项它决定了中间件在处理请求时使用哪一份微信配置Token、AppId、EncodingAESKey 等TextResponseLimitOptions为可选项用于限制文本返回长度示例设置为 2048 字符超长时可通过客服接口分段回复。中间件方式的底层原理UseMessageHandlerForWxOpen是 SDK 提供的扩展方法见 WxOpenMessageHandlerMiddleware.cs它内部将请求转交给WxOpenMessageHandlerMiddlewareTMC处理并以异步方式执行messageHandler.ExecuteAsync()public static IApplicationBuilder UseMessageHandlerForWxOpenTMC(this IApplicationBuilder builder, PathString pathMatch, FuncStream, PostModel, int, IServiceProvider, MessageHandlerTMC, IRequestMessageBase, IResponseMessageBase messageHandler, ActionMessageHandlerMiddlewareOptionsISenparcWeixinSettingForWxOpen options) where TMC : DefaultWxOpenMessageContext, IMessageContextIRequestMessageBase, IResponseMessageBase, new() { return builder.UseMessageHandlerWxOpenMessageHandlerMiddlewareTMC, TMC, PostModel, ISenparcWeixinSettingForWxOpen(pathMatch, messageHandler, options); }中间件内部封装了完整的两套流程GET 请求URL 验证GetCheckSignature()校验签名校验通过则直接输出echostr随机字符串返回给微信服务器完成配置验证WxOpenMessageHandlerMiddleware.csPOST 请求消息推送PostCheckSignature()先做签名校验校验通过后再进入消息处理管线WxOpenMessageHandlerMiddleware.cs。同时GetPostModel()从AccountSettingFunc返回的配置中读取WxOpenToken、WxOpenAppId、WxOpenEncodingAESKey并连同signature、timestamp、nonce、msg_signature等查询参数组装成PostModelWxOpenMessageHandlerMiddleware.cs开发者无需手工处理这些细节。中间件方式的扩展阅读官方博客《在 .NET Core 2.0/3.0 中使用 MessageHandler 中间件》同样适用于 .NET 6.0 及以上用法与公众号相同。3.2 方式二Controller 承载精细化控制当中间件的方式满足不了需求时例如需要在每个处理步骤之间插入自定义逻辑、干预签名校验、自定义异常处理流程等可以使用 Controller 将执行过程展开对每一步执行进行更加精确的控制或干预。使用 Controller 方式需要创建2 个 ActionActionName 都为Index分别对应微信后台验证Get 请求以及真实消息推送Post 请求。项目示例位于 WxOpenController.cs 中。GET ActionURL 验证[HttpGet] [ActionName(Index)] public ActionResult Get(PostModel postModel, string echostr) { if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { return Content(echostr); // 返回随机字符串则表示验证通过 } else { return Content(failed: postModel.Signature , MP.CheckSignature.GetSignature(postModel.Timestamp, postModel.Nonce, Token) 。 如果你在浏览器中看到这句话说明此地址可以被作为微信小程序后台的Url请注意保持Token一致。); } }POST Action消息推送处理[HttpPost] [ActionName(Index)] public ActionResult Post(PostModel postModel) { if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { return Content(参数错误); } postModel.Token Token; // 根据自己后台的设置保持一致 postModel.EncodingAESKey EncodingAESKey; // 根据自己后台的设置保持一致 postModel.AppId WxOpenAppId; // 根据自己后台的设置保持一致必须提供 // v4.2.2 之后的版本可以设置每个人上下文消息储存的最大数量防止内存占用过多如果该参数小于等于0则不限制 var maxRecordCount 10; // 自定义 MessageHandler对微信请求的详细判断操作都在这里面 var messageHandler new CustomWxOpenMessageHandler(Request.GetRequestMemoryStream(), postModel, maxRecordCount); try { /* 如果需要添加消息去重功能只需打开 OmitRepeatedMessage 功能SDK 会自动处理。 * 收到重复消息通常是因为微信服务器没有及时收到响应会持续发送 2-5 条不等的相同内容的 RequestMessage */ messageHandler.OmitRepeatedMessage true; // 测试时可开启此记录帮助跟踪数据使用前请确保 App_Data 文件夹存在且有读写权限。 messageHandler.SaveRequestMessageLog(); // 记录 Request 日志可选 messageHandler.Execute(); // 执行微信处理过程关键 messageHandler.SaveResponseMessageLog(); // 记录 Response 日志可选 return new FixWeixinBugWeixinResult(messageHandler); // 为了解决官方微信 5.0 软件换行 bug 暂时添加的方法 // return new WeixinResult(messageHandler); // v0.8 常规返回 } catch (Exception ex) { // 将异常详情含 InnerException 与 ResponseDocument写入 App_Data 目录下的日志文件 // ... return Content(); } }Controller 方式相比中间件的优势在于手动控制执行细节可以自行决定是否开启OmitRepeatedMessage消息去重、是否记录 Request/Response 日志SaveRequestMessageLog/SaveResponseMessageLog、以及异常发生时的自定义处理示例中会把完整异常栈与messageHandler.ResponseDocument写入App_Data下的日志文件可以自由扩展 Action同一个 Controller 中还能承载登录OnLogin、解密DecodeEncryptedData、DecryptPhoneNumber、订阅消息SubscribeMessage等其它小程序接口方便统一管理精确控制响应通过FixWeixinBugWeixinResult/WeixinResult包装返回结果。Controller 方式注意事项同步与异步示例 Controller 中使用的是同步messageHandler.Execute()这是历史兼容用法目前 SDK 已全面转向异步方法驱动官方建议使用messageHandler.ExecuteAsync()等异步方法见 WxOpenController.cs 的提示请求流读取需要Request.GetRequestMemoryStream()读取微信推送的请求流并将其作为CustomWxOpenMessageHandler构造参数之一AppId 必须提供postModel.AppId必须赋值示例中直接使用WxOpenAppId否则签名校验与后续消息处理可能失败。完成后即可通过 URL域名/WxOpen访问 MessageHandler设置为小程序后台的消息推送 URL。Controller 方式的扩展阅读官方博客《了解 MessageHandler》推荐使用全套异步方法基本用法与公众号相同。四、两种承载方式的对比与选型建议对比维度中间件方式推荐Controller 方式代码量极简仅Program.cs中一段注册代码需编写 2 个 Action 及完整处理流程新增文件无一个 Controller 文件可复用已有 ControllerURL 路径域名/WxOpenAsync可自定义 pathMatch域名/WxOpen由路由决定消息去重通过OmitRepeatedMessageFunc配置通过messageHandler.OmitRepeatedMessage true手动开启日志记录内置无需干预可手动调用SaveRequestMessageLog/SaveResponseMessageLog签名校验中间件自动完成GET/POST 均内置开发者手动调用CheckSignature.Check异常处理中间件默认处理开发者可完全自定义如写入日志文件扩展 Action不适用可在同一 Controller 中添加登录、解密等其它接口适用场景绝大多数常规项目需要精确干预每个处理步骤、特殊异常流程、混合多接口的场景选型建议常规项目直接使用中间件方式当需要展开执行过程、对每一步做精确控制或干预例如自定义日志、自定义异常兜底、与登录/解密等接口共存时切换到 Controller 方式。由于两者共用同一个CustomWxOpenMessageHandler迁移成本几乎为零甚至可以同时注册两个路径并存使用。五、前置配置与完整接入步骤要让 MessageHandler 真正跑起来还需要完成以下前置配置以 appsettings.json 为例。5.1 小程序账号配置在appsettings.json的SenparcWeixinSetting节点下需要配置小程序相关的四个参数{ SenparcWeixinSetting: { IsDebug: true, WxOpenAppId: 你的小程序AppId, WxOpenAppSecret: 你的小程序AppSecret, WxOpenToken: 你的Token与小程序后台一致, WxOpenEncodingAESKey: 你的EncodingAESKey与小程序后台一致 } }参数说明参数含义与后台的对应关系WxOpenAppId小程序 AppId小程序后台开发管理 → 开发设置中获取WxOpenAppSecret小程序 AppSecret与 AppId 同页获取注意保密WxOpenToken消息校验 Token消息推送配置时自定义的 Token区分大小写WxOpenEncodingAESKey消息加解密密钥消息推送配置时生成的 EncodingAESKey区分大小写说明配置文件中的占位符如#{WxOpenAppId}#是 Azure DevOps 默认占位符格式部署时请替换为明文真实值并删除两侧的#{}符号。WxOpenToken与WxOpenEncodingAESKey必须与小程序后台消息推送配置中的值完全一致区分大小写否则签名校验会失败。5.2 注册与启用在 Program.cs 中完成 Senparc.Weixin 的注入与注册// 注入 builder.Services.AddSenparcWeixin(builder.Configuration); // 注册app 构建之后 var registerService app.UseSenparcWeixin(app.Environment, null /* 传入 null 则使用 appsettings 中的 SenparcSetting 配置 */, null /* 传入 null 则使用 appsettings 中的 SenparcWeixinSetting 配置 */, register { }, (register, weixinSetting) { // 注册小程序账号信息示例 register.RegisterWxOpenAccount(weixinSetting, 盛派小助手·小程序); });5.3 后台消息 URL 配置最后在小程序后台的开发管理 → 开发设置 → 消息推送中服务器地址URL填写https://你的域名/WxOpenAsync中间件方式或https://你的域名/WxOpenController 方式Token 与 EncodingAESKey 与appsettings.json中配置保持一致提交后微信服务器会发起一次 GET 请求校验 URL校验通过后即可开始接收消息推送。六、扩展阅读中间件方式官方博客《在 .NET Core 2.0/3.0 中使用 MessageHandler 中间件》同样适用于 .NET 6.0 及以上用法与公众号相同Controller 方式官方博客《了解 MessageHandler》推荐使用全套异步方法更多小程序相关指南可参考 docs/en/guide/wxopen/ 与 docs/zh/guide/wxopen/ 目录下的系列文档中间件完整源码WxOpenMessageHandlerMiddleware.cs基类消息路由与处理方法WxOpenMessageHandler.cs、WxOpenMessageHandler.Message.cs完整示例项目Samples/WxOpen/Senparc.Weixin.Sample.WxOpen/含 MessageHandlers、Controllers、Program.cs、appsettings.json。赞分享后端即时通讯金融科技【免费下载链接】WeiXinMPSDK微信全平台 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 WeChat SDK for C#.项目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK点击查看免费下载相关推荐Senparc.Weixin 小程序 MessageHandler自定义消息处理器与中间件/Controller 两种承载方式Senparc.Weixin 小程序 MessageHandler自定义消息处理器与中间件/Controller 两种承载方式 在微信小程序服务端开发中客服后端即时通讯金融科技Senparc.Weixin 企业微信 MessageHandler 实战自定义消息处理器与中间件、Controller 两种承载方式Senparc.Weixin 企业微信 MessageHandler 实战自定义消息处理器与中间件、Controller 两种承载方式 本文基于仓库文档 Me后端即时通讯金融科技WeiXinMPSDK 企业微信 MessageHandler 开发指南自定义消息处理类的两种承载方式与源码级实现WeiXinMPSDK 企业微信 MessageHandler 开发指南自定义消息处理类的两种承载方式与源码级实现 企业微信Work应用接收来自对话窗口的后端即时通讯金融科技上一篇tuigreet完全指南打造高效控制台登录体验的终极方案下一篇LunaTranslator OCR 自动化执行全解析四种截图触发方式与阈值参数调优指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网