JeffreySu/WeiXinMPSDK · error · ArgumentNullException

brandApiCredentials

Error message

brandApiCredentials

What it means

The internal TenPayHttpHandler(TenPayBrandApiCredentials) constructor uses a throw-expression on its argument, so passing null for brandApiCredentials throws ArgumentNullException with param name 'brandApiCredentials'. Brand credentials are mandatory for this constructor overload.

Solutions

  1. Construct a valid TenPayBrandApiCredentials before creating the handler.
  2. If brand credentials are optional, use the setting-based constructor TenPayHttpHandler(ISenparcWeixinSettingForTenpayV3) or the two-argument private path via the public overload instead.
  3. Check DI registrations so TenPayBrandApiCredentials is registered and configured.
  4. Null-check the credentials at the call site to produce a clearer application-level error.

Example fix

// before
var handler = new TenPayHttpHandler((TenPayBrandApiCredentials)null);
// after
var creds = new TenPayBrandApiCredentials(mchId, serial, publicKeyPem, privateKeyPem);
var handler = new TenPayHttpHandler(creds);
Defensive patterns

Strategy: validation

Validate before calling

if (brandCredentials == null)
    throw new InvalidOperationException("Brand credentials must be constructed before creating TenPayHttpHandler.");
var handler = new TenPayHttpHandler(brandCredentials);

Type guard

bool HasBrandCredentials(TenPayBrandApiCredentials? c) => c is not null;

Try / catch

try { handler = new TenPayHttpHandler(brandCredentials); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Brand credentials were null — check DI registration"); throw; }

Prevention

When it happens

Trigger: Calling new TenPayHttpHandler((TenPayBrandApiCredentials)null) directly, or via DI/factory where the TenPayBrandApiCredentials registration resolved to null.

Common situations: DI container returning null for an unregistered TenPayBrandApiCredentials; a factory method returning null when brand config is absent; casting/overload resolution picking the brand-credentials overload unintentionally with a null literal.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayHttpHandler.cs:85

        //    InnerHandler = new HttpClientHandler();

        //    this.merchantId = merchantId;
        //    this.serialNo = merchantSerialNo;
        //    this.privateKey = privateKey;
        //}

        //TODO: 此处重构使用ISenparcWeixinSettingForTenpayV3初始化实例
        private readonly ISenparcWeixinSettingForTenpayV3 _tenpayV3Setting;
        private readonly TenPayBrandApiCredentials _brandApiCredentials;

        public TenPayHttpHandler(ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3 = null)
            : this(senparcWeixinSettingForTenpayV3, null)
        {
        }

        internal TenPayHttpHandler(TenPayBrandApiCredentials brandApiCredentials)
            : this(null, brandApiCredentials ??
                throw new ArgumentNullException(nameof(brandApiCredentials)))
        {
        }

        private TenPayHttpHandler(
            ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3,
            TenPayBrandApiCredentials brandApiCredentials)
        {
            InnerHandler = new HttpClientHandler();

            _brandApiCredentials = brandApiCredentials;
            if (_brandApiCredentials != null)
            {
                return;
            }

            _tenpayV3Setting = senparcWeixinSettingForTenpayV3 ?? Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;

            if (!_tenpayV3Setting.EncryptionType.HasValue)

View on GitHub (pinned to be573f6f94)