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
- Construct a valid TenPayBrandApiCredentials before creating the handler.
- If brand credentials are optional, use the setting-based constructor TenPayHttpHandler(ISenparcWeixinSettingForTenpayV3) or the two-argument private path via the public overload instead.
- Check DI registrations so TenPayBrandApiCredentials is registered and configured.
- 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
- Register TenPayBrandApiCredentials in DI before registering the handler.
- Null-check factory outputs before constructing handlers.
- Use the settings-based constructor when brand credentials are optional.
- Fail fast at startup if brand credentials are required but missing.
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)