{"record":{"id":"93a035e336061e93","repo":"JeffreySu/WeiXinMPSDK","slug":"argumentnullexception-response-is-null","errorCode":null,"errorMessage":"ArgumentNullException (response is null)","messagePattern":"ArgumentNullException \\(response is null\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OpenHardware/OpenHardwareCallbackHandler.cs","lineNumber":162,"sourceCode":"        /// 将强类型被动响应序列化、加密并生成企业微信要求的签名字段。\n        /// </summary>\n        /// <typeparam name=\"TResponse\">开放硬件被动响应类型。</typeparam>\n        /// <param name=\"token\">开放硬件回调地址配置的 Token。</param>\n        /// <param name=\"encodingAesKey\">开放硬件回调地址配置的 EncodingAESKey。</param>\n        /// <param name=\"receiveId\">接收方标识；服务商通用地址传 CorpId，型号地址传 ModelId。</param>\n        /// <param name=\"timestamp\">生成签名使用的时间戳。</param>\n        /// <param name=\"nonce\">生成签名使用的随机字符串。</param>\n        /// <param name=\"response\">需要加密的强类型被动响应。</param>\n        /// <returns>可直接序列化返回的加密响应结构。</returns>\n        /// <exception cref=\"ArgumentNullException\">被动响应对象为 null 时抛出。</exception>\n        /// <exception cref=\"OpenHardwareCallbackCryptException\">加密或生成签名失败时抛出。</exception>\n        public static OpenHardwareEncryptedCallbackReply EncryptResponse<TResponse>(\n            string token, string encodingAesKey, string receiveId,\n            string timestamp, string nonce, TResponse response)\n        {\n            if (response == null)\n            {\n                throw new ArgumentNullException(nameof(response));\n            }\n\n            var plaintext = JsonConvert.SerializeObject(response,\n                new JsonSerializerSettings\n                {\n                    NullValueHandling = NullValueHandling.Ignore\n                });\n            return EncryptResponse(token, encodingAesKey, receiveId, timestamp,\n                nonce, plaintext);\n        }\n\n        /// <summary>\n        /// 加密被动响应明文并生成企业微信要求的签名字段。\n        /// </summary>\n        /// <param name=\"token\">开放硬件回调地址配置的 Token。</param>\n        /// <param name=\"encodingAesKey\">开放硬件回调地址配置的 EncodingAESKey。</param>\n        /// <param name=\"receiveId\">接收方标识；服务商通用地址传 CorpId，型号地址传 ModelId。</param>\n        /// <param name=\"timestamp\">生成签名使用的时间戳。</param>","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OpenHardware/OpenHardwareCallbackHandler.cs#L144-L180","documentation":"EncryptResponse serializes an OpenHardware callback reply to JSON and encrypts it for the WeChat Work OpenHardware callback protocol. It throws ArgumentNullException when the response object passed via the generic TResponse parameter is null, because there is nothing to serialize or encrypt.","triggerScenarios":"Calling OpenHardwareCallbackHandler.EncryptResponse(token, encodingAesKey, receiveId, timestamp, nonce, null) — i.e. the reply object constructed for a callback is null, typically when a handler method returns null instead of a reply instance.","commonSituations":"A callback handler builds the reply conditionally (e.g. only on success) and forgets to return an object in the failure branch; a factory method returning null; refactoring that changed an early-return path to return null instead of a default reply.","solutions":["Construct and pass a non-null OpenHardwareEncryptedCallbackReply (or the applicable TResponse) to EncryptResponse","Check the handler/branch that produced the reply and return a default/reply object instead of null","Guard the call site with a null check before invoking EncryptResponse"],"exampleFix":"// before\nOpenHardwareEncryptedCallbackReply reply = BuildReply(request); // may return null\nvar encrypted = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply);\n// after\nOpenHardwareEncryptedCallbackReply reply = BuildReply(request) ?? new OpenHardwareEncryptedCallbackReply();\nvar encrypted = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply);","handlingStrategy":"validation","validationCode":"if (response is null) throw new InvalidOperationException(\"Cannot encrypt a null OpenHardware callback reply\");","typeGuard":"bool HasReply<TResponse>(TResponse r) => r is not null;","tryCatchPattern":"try { var enc = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply); }\ncatch (ArgumentNullException ex) { logger.LogError(ex, \"Reply was null\"); return null; }","preventionTips":["Always return a concrete reply object from handler methods, never null","Use nullable reference types so null flows are flagged at compile time","Write a unit test that exercises every branch that produces the reply"],"tags":["null-reference","argument-validation","csharp","wechat-work"],"backgroundTag":"null-argument","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"}