JeffreySu/WeiXinMPSDK · error · ArgumentNullException

uri

Error message

uri

What it means

XPayApi.GeneratePaySign throws ArgumentNullException when the uri parameter is null, empty, or whitespace. The uri (request URI path) is required as part of the raw signature string ($"{uri}&{signData}").

Solutions

  1. Pass the correct XPay endpoint URI string as the second argument
  2. Define endpoint paths as constants to avoid null/empty values
  3. Add a guard or default in your wrapper service

Example fix

// before
var sign = XPayApi.GeneratePaySign(appKey, null, data);
// after
var sign = XPayApi.GeneratePaySign(appKey, "/xpay/currency/pay", data);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(uri)) throw new InvalidOperationException("XPay endpoint URI is required");

Try / catch

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

Prevention

When it happens

Trigger: Calling GeneratePaySign with uri = null or "", typically because the endpoint path constant was not passed or a config value is blank.

Common situations: Forgot to pass the API path (e.g. "/xpay/query_user_balance") when wrapping the call; refactoring removed the uri argument; config-driven uri not set.

Related errors


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

Appendix: source

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

        #region 扩展方法
        /// <summary>
        /// 生成pay_sig
        /// </summary>
        /// <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();
            }
        }

View on GitHub (pinned to be573f6f94)