JeffreySu/WeiXinMPSDK · error · ArgumentNullException

brandApiCredentials

Error message

brandApiCredentials

What it means

A standard ArgumentNullException raised in the private TenPayApiRequest constructor when the brandApiCredentials parameter is null. This constructor is used for WeChat Pay brand API (品牌) requests and cannot create a client without credentials.

Solutions

  1. Provide a fully initialized TenPayBrandApiCredentials (cert key, serial number, etc.) before constructing the request
  2. Guard with ArgumentNullException.ThrowIfNull at your own call site to fail earlier with clearer context
  3. Verify brand credentials are loaded from configuration correctly

Example fix

// before
var req = new TenPayApiRequest((TenPayBrandApiCredentials)null);
// after
var creds = new TenPayBrandApiCredentials { /* load cert + serial */ };
var req = new TenPayApiRequest(creds);
Defensive patterns

Strategy: try-catch

Validate before calling

if (brandApiCredentials == null)
    throw new InvalidOperationException("品牌 API 凭证未配置");

Try / catch

try { var req = new TenPayApiRequest(credentials); }
catch (ArgumentNullException ex) when (ex.ParamName == "brandApiCredentials") { log.Error("品牌 API 凭证为空", ex); throw; }

Prevention

When it happens

Trigger: Constructing TenPayApiRequest via the internal/private overload with a null TenPayBrandApiCredentials, e.g. credentials failed to load from config or a factory returned null.

Common situations: Missing brand API credentials (证书/serial) in configuration; a DI or factory path passing an uninitialized credentials object.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs:101

        private static readonly ConditionalWeakTable<Action<HttpClient>, ConditionalWeakTable<ISenparcWeixinSettingForTenpayV3, Lazy<HttpClient>>> CustomHttpClients = new();
        private static readonly ConditionalWeakTable<TenPayBrandApiCredentials, Lazy<HttpClient>> BrandHttpClients = new();

        private readonly ISenparcWeixinSettingForTenpayV3 _tenpayV3Setting;
        private readonly TenPayBrandApiCredentials _brandApiCredentials;
        private readonly Action<HttpClient> _setHeaderAction;
        private readonly Lazy<HttpClient> _client;

        public TenPayApiRequest(ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3 = null, Action<HttpClient> setHeaderAction = null)
        {
            _tenpayV3Setting = senparcWeixinSettingForTenpayV3 ?? Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;
            _setHeaderAction = setHeaderAction;
            _client = GetOrCreateHttpClient(_tenpayV3Setting, _setHeaderAction);
        }

        private TenPayApiRequest(TenPayBrandApiCredentials brandApiCredentials)
        {
            _brandApiCredentials = brandApiCredentials ??
                throw new ArgumentNullException(nameof(brandApiCredentials));
            _client = BrandHttpClients.GetValue(_brandApiCredentials,
                credentials => new Lazy<HttpClient>(
                    () => CreateBrandHttpClient(credentials),
                    LazyThreadSafetyMode.ExecutionAndPublication));
        }

        /// <summary>
        /// 创建使用微信支付品牌 API 专用鉴权的请求实例。
        /// </summary>
        /// <param name="brandApiCredentials">品牌 ID、品牌 API 证书和微信支付公钥凭据。</param>
        /// <returns>使用 <c>WECHATPAY-BRAND-SHA256-RSA2048</c> 认证类型的请求实例。</returns>
        public static TenPayApiRequest CreateForBrand(
            TenPayBrandApiCredentials brandApiCredentials)
        {
            return new TenPayApiRequest(brandApiCredentials);
        }

        private static Lazy<HttpClient> GetOrCreateHttpClient(ISenparcWeixinSettingForTenpayV3 setting, Action<HttpClient> setHeaderAction)

View on GitHub (pinned to be573f6f94)