JeffreySu/WeiXinMPSDK · error · ArgumentNullException

data

Error message

data

What it means

XPayApi.GeneratePaySign builds the request signature for WeChat mini-game virtual-payment (xpay) endpoints by serializing the request payload T data and HMAC-signing it with appKey and uri. It throws ArgumentNullException when data is null: there is no payload to sign, so no valid signature can be produced. The method explicitly documents ArgumentNullException; the offending input here is the data object, which must be non-null alongside appKey and uri for signature generation.

Solutions

  1. Check the data object for null before calling GeneratePaySign
  2. Fail earlier in the flow when the payload could not be built
  3. Construct a valid payload object even when upstream data is absent

Example fix

// before
var sign = XPayApi.GeneratePaySign(appKey, uri, order); // order may be null
// after
if (order == null) throw new InvalidOperationException("order payload missing");
var sign = XPayApi.GeneratePaySign(appKey, uri, order);
Defensive patterns

Strategy: validation

Validate before calling

if (data == null) throw new InvalidOperationException("XPay payload must not be null");

Type guard

bool HasPayload<T>(T data) => data is not null;

Try / catch

try { return XPayApi.GeneratePaySign(appKey, uri, data); }
catch (ArgumentNullException ex) { logger.LogError(ex, "XPay data payload missing"); throw; }

Prevention

When it happens

Trigger: Calling GeneratePaySign(appKey, uri, null) — usually the result of an upstream query that produced null and was passed straight through to the signing call.

Common situations: Upstream order/balance query returned null and the code did not check before signing; generic type T instantiated with a null reference.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/AdvancedAPIs/XPay/XPayApi.cs:1289

        /// <typeparam name="T"></typeparam>
        /// <param name="appKey"></param>
        /// <param name="uri">例:/xpay/query_user_balance</param>
        /// <param name="data"></param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static string GeneratePaySign<T>(string appKey, string uri, T data)
        {
            if (string.IsNullOrWhiteSpace(appKey))
            {
                throw new ArgumentNullException("appKey");
            }
            if (string.IsNullOrWhiteSpace(uri))
            {
                throw new ArgumentNullException("uri");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var signData = JsonConvert.SerializeObject(data);
            var rawData = $"{uri}&{signData}";

            var keyBytes = Encoding.UTF8.GetBytes(appKey);
            var dataBytes = Encoding.UTF8.GetBytes(rawData);
            using (var hmac = new HMACSHA256(keyBytes))
            {
                var hashBytes = hmac.ComputeHash(dataBytes);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }
        }

        /// <summary>
        /// 生成signature
        /// </summary>
        /// <typeparam name="T"></typeparam>

View on GitHub (pinned to be573f6f94)