JeffreySu/WeiXinMPSDK · error · ArgumentNullException

ArgumentNullException (request is null)

Error message

ArgumentNullException (request is null)

What it means

PayToolSignatureHelper.PrepareRequest signs (or validates pre-signature fields of) a WeChat Work PayTool (收银台) API request. It throws ArgumentNullException when the request object itself is null, because no signature parameters can be computed without it.

Solutions

  1. Construct the PayToolSignedRequestBase instance (e.g. PayToolOrderRequest) before calling PrepareRequest
  2. Check the code path that produced the request and ensure it always returns a populated object
  3. Add a null check at the call site before invoking PrepareRequest

Example fix

// before
PayToolSignedRequestBase req = CreateRequest(); // may be null
PayToolSignatureHelper.PrepareRequest(req, apiSecret);
// after
PayToolSignedRequestBase req = CreateRequest() ?? throw new InvalidOperationException("request not built");
PayToolSignatureHelper.PrepareRequest(req, apiSecret);
Defensive patterns

Strategy: validation

Validate before calling

if (request is null) throw new InvalidOperationException("PayTool request must be constructed before PrepareRequest");

Type guard

bool IsReady(PayToolSignedRequestBase r) => r is not null;

Try / catch

try { PayToolSignatureHelper.PrepareRequest(req, apiSecret); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Request was null"); return null; }

Prevention

When it happens

Trigger: Calling PrepareRequest(null, payToolApiSecret) — e.g. a factory/builder returned null or a deserialized request was null before signature preparation.

Common situations: API response/deserialization produced a null request model; a conditional code path skipped request construction; unit tests passing null; refactoring where the request creation moved after the PrepareRequest call.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/PayTool/PayToolSignatureHelper.cs:40

namespace Senparc.Weixin.Work.AdvancedAPIs.PayTool
{
    /// <summary>
    /// 企业微信收款工具 HMAC-SHA256 签名辅助方法。
    /// </summary>
    public static class PayToolSignatureHelper
    {
        /// <summary>
        /// 为收款工具请求补齐随机串、Unix 时间戳和数字签名。
        /// 已提供签名时不会重新签名,并要求调用方同时提供原签名对应的随机串和时间戳。
        /// </summary>
        /// <param name="request">需要签名的收款工具请求。</param>
        /// <param name="payToolApiSecret">收银台 API 调用密钥;请求未预签名时必填。</param>
        public static void PrepareRequest(PayToolSignedRequestBase request,
            string payToolApiSecret)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (!string.IsNullOrEmpty(request.sig))
            {
                if (string.IsNullOrEmpty(request.nonce_str) || request.ts <= 0)
                {
                    throw new ArgumentException("预签名请求必须同时提供 nonce_str 和 ts。",
                        nameof(request));
                }

                return;
            }

            if (string.IsNullOrEmpty(payToolApiSecret))
            {
                throw new ArgumentException("请求未提供 sig 时必须提供收银台 API 调用密钥。",
                    nameof(payToolApiSecret));
            }

View on GitHub (pinned to be573f6f94)