JeffreySu/WeiXinMPSDK · error · UnknownRequestMsgTypeException

未知的MsgType请求类型

Error message

未知的MsgType请求类型

What it means

The default branch of BuildResponseMessageAsync's MsgType switch throws UnknownRequestMsgTypeException when the request's MsgType matches no handled case. It is the final catch-all guard ensuring every WeCom callback message type is explicitly routed to an On*Request method.

Solutions

  1. Upgrade Senparc.Weixin.Work to the newest release to gain support for the new MsgType
  2. Derive from WorkMessageHandler and override the handler for the new message type if available in the entity model
  3. Wrap BuildResponseMessageAsync / handler execution in a try-catch for UnknownRequestMsgTypeException and log the raw XML for analysis
  4. Inspect the raw callback XML to confirm which MsgType string fails to deserialize to a known enum

Example fix

// before
var result = await handler.BuildResponseMessageAsync();
// after
try { var result = await handler.BuildResponseMessageAsync(); }
catch (UnknownRequestMsgTypeException ex) { _logger.LogWarning(ex, "Unhandled WeCom MsgType: {MsgType}", postModel.MsgType); }
Defensive patterns

Strategy: try-catch

Validate before calling

var known = new[]{ RequestMsgType.Text, RequestMsgType.Image, RequestMsgType.Voice, RequestMsgType.Video, RequestMsgType.Location, RequestMsgType.Link, RequestMsgType.ShortVideo, RequestMsgType.Event }; if (!known.Contains(requestMessage.MsgType)) { return null; }

Type guard

bool HasKnownMsgType(IRequestMessageBase msg) => Enum.IsDefined(typeof(RequestMsgType), msg.MsgType) && msg.MsgType != RequestMsgType.Unknown;

Try / catch

try { response = await handler.BuildResponseMessageAsync(); } catch (UnknownRequestMsgTypeException ex) { _logger.LogWarning(ex, "Unknown MsgType: {MsgType}", rawMsgType); return Content("success"); }

Prevention

When it happens

Trigger: A WeCom callback whose MsgType value is not among the handled cases (Text, Image, Voice, Video, Location, Link, ShortVideo, Event, etc.) reaches BuildResponseMessageAsync — typically a newly introduced MsgType from Tencent or a corrupted/incorrectly deserialized message.

Common situations: WeCom adds a new callback message type before the library supports it; custom mock messages used in tests with an invalid MsgType; message decryption/deserialization producing a wrong enum value.

Related errors


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

Appendix: source

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

                case RequestMsgType.Video:
                    ResponseMessage = await OnVideoRequestAsync(RequestMessage as RequestMessageVideo);
                    break;
                case RequestMsgType.ShortVideo:
                    ResponseMessage = await OnShortVideoRequestAsync(RequestMessage as RequestMessageShortVideo);
                    break;
                case RequestMsgType.File:
                    ResponseMessage = await OnFileRequestAsync(RequestMessage as RequestMessageFile);
                    break;
                case RequestMsgType.Event:
                {
                    var requestMessageText = (RequestMessage as IRequestMessageEventBase).ConvertToRequestMessageText();

                    ResponseMessage = await OnTextOrEventRequestAsync(requestMessageText) ??
                                      await OnEventRequestAsync(RequestMessage as IRequestMessageEventBase);
                }
                    break;
                default:
                    throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
            }
        }


        #region 接收消息方法

        public virtual async Task<IWorkResponseMessageBase> DefaultResponseMessageAsync(
            IWorkRequestMessageBase requestMessage)
        {
            return await Task.FromResult(DefaultResponseMessage(requestMessage)).ConfigureAwait(false);
        }

        /// <summary>
        /// 预处理文字或事件类型请求。
        /// 这个请求是一个比较特殊的请求,通常用于统一处理来自文字或菜单按钮的同一个执行逻辑,
        /// 会在执行OnTextRequest或OnEventRequest之前触发,具有以下一些特征:
        /// 1、如果返回null,则继续执行OnTextRequest或OnEventRequest
        /// 2、如果返回不为null,则终止执行OnTextRequest或OnEventRequest,返回最终ResponseMessage

View on GitHub (pinned to be573f6f94)