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
- 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
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
- 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
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)