JeffreySu/WeiXinMPSDK · error · WeixinException

没有找到合适的消息类型。

Error message

没有找到合适的消息类型。

What it means

WorkMessageHandler's async BuildResponseMessageAsync dispatches on the request message type; when the message implements neither a known normal message type nor a third-party info interface, it cannot build a response and throws WeixinException. This guards the handler against receiving message classes the Work (WeCom) handler does not recognize.

Solutions

  1. Check that the incoming message is deserialized as a Senparc.Weixin.Work request message type and routed to WorkMessageHandler, not another platform's handler
  2. Upgrade Senparc.Weixin.Work / Senparc.Weixin.SDK to the latest version so new WeCom message types are supported
  3. Override OnTextOrEventRequestAsync or the relevant On*Request method and/or extend the message-type switch in a derived handler to cover your message type
  4. Log RequestMessage.MsgType and the concrete RequestMessage class to identify the unmapped type before handling

Example fix

// before (derived handler throws on unknown type)
var handler = new WorkMessageHandler<int>(requestMsg, stream, maxRecordSize, postModel);
// after: pre-check the message type and skip unknown ones
if (requestMessage.MsgType == RequestMsgType.Unknown) { return; }
var handler = new WorkMessageHandler<int>(requestMsg, stream, maxRecordSize, postModel);
Defensive patterns

Strategy: try-catch

Validate before calling

if (requestMessage == null || requestMessage.MsgType == RequestMsgType.Unknown) { return null; }

Type guard

bool IsSupportedWorkMessage(IRequestMessageBase msg) => msg is IRequestMessageText || msg is IRequestMessageEventBase || msg is IRequestMessageImage || msg is IRequestMessageVoice || msg is IRequestMessageVideo || msg is IRequestMessageLocation || msg is IThirdPartyInfoBase;

Try / catch

try { response = await handler.BuildResponseMessageAsync(); } catch (WeixinException ex) { _logger.LogWarning(ex, "Unmapped Work message type: {Type}", requestMessage?.MsgType); response = null; }

Prevention

When it happens

Trigger: Calling BuildResponseMessageAsync (directly or via message handler execution) with a RequestMessage whose type is not one of the handled MsgTypes and which cannot be cast to IThirdPartyInfoBase — e.g. a custom/unknown message model, or a message type not yet mapped in the switch.

Common situations: Feeding an MP (Official Account) message object into the Work handler; a new WeCom callback message type added by Tencent but not yet supported by the installed library version; manually constructing a request message with an unmapped MsgType for unit tests.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/0e145b8c8e35d4be. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/MessageHandlers/Async/WorkMessageHandler.Async.cs:68

{
    public abstract partial class WorkMessageHandler<TMC>
        : MessageHandler<TMC, IWorkRequestMessageBase, IWorkResponseMessageBase>, IWorkMessageHandler
        where TMC : class, IMessageContext<IWorkRequestMessageBase, IWorkResponseMessageBase>, new()
    {
        public override async Task BuildResponseMessageAsync(CancellationToken cancellationToken)
        {
            switch (RequestMessage.MsgType)
            {
                case RequestMsgType.Unknown: //第三方回调
                {
                    if (RequestMessage is IThirdPartyInfoBase)
                    {
                        var thirdPartyInfo = RequestMessage as IThirdPartyInfoBase;
                        TextResponseMessage = await OnThirdPartyEventAsync(thirdPartyInfo);
                    }
                    else
                    {
                        throw new WeixinException("没有找到合适的消息类型。");
                    }
                }
                    break;
                //以下是普通信息
                case RequestMsgType.Text:
                {
                    var requestMessage = RequestMessage as RequestMessageText;

                    ResponseMessage = await OnTextOrEventRequestAsync(requestMessage) ??
                                      await OnTextRequestAsync(requestMessage);
                }
                    break;
                case RequestMsgType.Location:
                    ResponseMessage = await OnLocationRequestAsync(RequestMessage as RequestMessageLocation);
                    break;
                case RequestMsgType.Image:
                    ResponseMessage = await OnImageRequestAsync(RequestMessage as RequestMessageImage);
                    break;

View on GitHub (pinned to be573f6f94)