{"record":{"id":"adb8bad45f1ea807","repo":"JeffreySu/WeiXinMPSDK","slug":"json","errorCode":null,"errorMessage":"专区程序事件 JSON 不能为空。","messagePattern":"专区程序事件 JSON 不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/DataIntelligence/ChatDataCallbackHandler.cs","lineNumber":38,"sourceCode":"{\n    /// <summary>\n    /// 数据与智能专区程序 JSON 回调处理器。\n    /// <para>企业微信专区 SDK 会将事件 JSON 字符串传入注册回调函数的 data 参数。</para>\n    /// </summary>\n    public static class ChatDataCallbackHandler\n    {\n        /// <summary>\n        /// 根据 event_type 将专区程序事件 JSON 分派为强类型消息。\n        /// </summary>\n        /// <param name=\"json\">专区 SDK 回调函数收到的完整 data JSON 字符串。</param>\n        /// <returns>已识别的强类型事件；未知事件保留原始 JSON。</returns>\n        /// <exception cref=\"ArgumentException\">JSON 字符串为空时抛出。</exception>\n        /// <exception cref=\"JsonReaderException\">输入不是合法 JSON 时抛出。</exception>\n        public static ChatDataCallbackEventBase Parse(string json)\n        {\n            if (string.IsNullOrWhiteSpace(json))\n            {\n                throw new ArgumentException(\"专区程序事件 JSON 不能为空。\", nameof(json));\n            }\n\n            var root = JObject.Parse(json);\n            var eventType = (string)root[\"event_type\"];\n            switch (eventType)\n            {\n                case ChatDataCallbackTypes.AuditApprovedSingle:\n                case ChatDataCallbackTypes.AuditApprovedRoom:\n                    return Deserialize<ChatDataAuditApprovedCallback>(json);\n                case ChatDataCallbackTypes.ConversationNewMessage:\n                    return Deserialize<ChatDataConversationNewMessageCallback>(json);\n                case ChatDataCallbackTypes.HitKeyword:\n                    return Deserialize<ChatDataHitKeywordCallback>(json);\n                case ChatDataCallbackTypes.AuthorizeKnowledgeBase:\n                case ChatDataCallbackTypes.UnauthorizeKnowledgeBase:\n                case ChatDataCallbackTypes.DeleteKnowledgeBase:\n                case ChatDataCallbackTypes.KnowledgeBaseLearnDone:\n                    return Deserialize<ChatDataKnowledgeBaseCallback>(json);","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/DataIntelligence/ChatDataCallbackHandler.cs#L20-L56","documentation":"ChatDataCallbackHandler.Parse parses WeCom DataIntelligence (专区程序) callback JSON. It throws ArgumentException when the json argument is null, empty, or whitespace, since no event can be derived from an empty payload.","triggerScenarios":"Passing null/empty string to Parse, e.g. reading an empty request body, a missing callback body in a controller, or a stream that was consumed before reading.","commonSituations":"Webhook endpoints that don't read the request body correctly, callback replay/test tools sending empty bodies, frameworks reading the body twice.","solutions":["Read the full request body before parsing: using var reader = new StreamReader(req.Body); var json = await reader.ReadToEndAsync();","Guard in the caller: if (string.IsNullOrWhiteSpace(json)) return early with 400","Ensure the webhook signature/decrypt step output (the plaintext json) is actually passed, not an intermediate empty value"],"exampleFix":"// before\nvar evt = ChatDataCallbackHandler.Parse(request.Body);\n// after\nvar json = await new StreamReader(request.Body).ReadToEndAsync();\nif (string.IsNullOrWhiteSpace(json)) return BadRequest(\"empty body\");\nvar evt = ChatDataCallbackHandler.Parse(json);","handlingStrategy":"try-catch","validationCode":"if (string.IsNullOrWhiteSpace(json)) return Results.BadRequest(\"Empty callback body\");","typeGuard":null,"tryCatchPattern":"try { var evt = ChatDataCallbackHandler.Parse(json); } catch (ArgumentException) { log.Warn(\"Empty DataIntelligence callback body\"); return Results.BadRequest(); } catch (JsonReaderException ex) { log.Warn(ex, \"Invalid callback JSON\"); return Results.BadRequest(); }","preventionTips":["Always read the full request body exactly once before parsing","Log raw body (truncated) on parse failure for diagnostics","Return 4xx for empty bodies so senders are alerted"],"tags":["json","validation","callback","wecom"],"backgroundTag":"empty-required-field","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}