JeffreySu/WeiXinMPSDK · error · ArgumentNullException

ArgumentNullException (response is null)

Error message

ArgumentNullException (response is null)

What it means

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.

Solutions

  1. Construct and pass a non-null OpenHardwareEncryptedCallbackReply (or the applicable TResponse) to EncryptResponse
  2. Check the handler/branch that produced the reply and return a default/reply object instead of null
  3. Guard the call site with a null check before invoking EncryptResponse

Example fix

// before
OpenHardwareEncryptedCallbackReply reply = BuildReply(request); // may return null
var encrypted = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply);
// after
OpenHardwareEncryptedCallbackReply reply = BuildReply(request) ?? new OpenHardwareEncryptedCallbackReply();
var encrypted = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply);
Defensive patterns

Strategy: validation

Validate before calling

if (response is null) throw new InvalidOperationException("Cannot encrypt a null OpenHardware callback reply");

Type guard

bool HasReply<TResponse>(TResponse r) => r is not null;

Try / catch

try { var enc = OpenHardwareCallbackHandler.EncryptResponse(token, key, receiveId, ts, nonce, reply); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Reply was null"); return null; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OpenHardware/OpenHardwareCallbackHandler.cs:162

        /// 将强类型被动响应序列化、加密并生成企业微信要求的签名字段。
        /// </summary>
        /// <typeparam name="TResponse">开放硬件被动响应类型。</typeparam>
        /// <param name="token">开放硬件回调地址配置的 Token。</param>
        /// <param name="encodingAesKey">开放硬件回调地址配置的 EncodingAESKey。</param>
        /// <param name="receiveId">接收方标识;服务商通用地址传 CorpId,型号地址传 ModelId。</param>
        /// <param name="timestamp">生成签名使用的时间戳。</param>
        /// <param name="nonce">生成签名使用的随机字符串。</param>
        /// <param name="response">需要加密的强类型被动响应。</param>
        /// <returns>可直接序列化返回的加密响应结构。</returns>
        /// <exception cref="ArgumentNullException">被动响应对象为 null 时抛出。</exception>
        /// <exception cref="OpenHardwareCallbackCryptException">加密或生成签名失败时抛出。</exception>
        public static OpenHardwareEncryptedCallbackReply EncryptResponse<TResponse>(
            string token, string encodingAesKey, string receiveId,
            string timestamp, string nonce, TResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            var plaintext = JsonConvert.SerializeObject(response,
                new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore
                });
            return EncryptResponse(token, encodingAesKey, receiveId, timestamp,
                nonce, plaintext);
        }

        /// <summary>
        /// 加密被动响应明文并生成企业微信要求的签名字段。
        /// </summary>
        /// <param name="token">开放硬件回调地址配置的 Token。</param>
        /// <param name="encodingAesKey">开放硬件回调地址配置的 EncodingAESKey。</param>
        /// <param name="receiveId">接收方标识;服务商通用地址传 CorpId,型号地址传 ModelId。</param>
        /// <param name="timestamp">生成签名使用的时间戳。</param>

View on GitHub (pinned to be573f6f94)