{"record":{"id":"c85d1e621e7de244","repo":"JeffreySu/WeiXinMPSDK","slug":"brandapicredentials","errorCode":null,"errorMessage":"brandApiCredentials","messagePattern":"brandApiCredentials","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs","lineNumber":101,"sourceCode":"        private static readonly ConditionalWeakTable<Action<HttpClient>, ConditionalWeakTable<ISenparcWeixinSettingForTenpayV3, Lazy<HttpClient>>> CustomHttpClients = new();\n        private static readonly ConditionalWeakTable<TenPayBrandApiCredentials, Lazy<HttpClient>> BrandHttpClients = new();\n\n        private readonly ISenparcWeixinSettingForTenpayV3 _tenpayV3Setting;\n        private readonly TenPayBrandApiCredentials _brandApiCredentials;\n        private readonly Action<HttpClient> _setHeaderAction;\n        private readonly Lazy<HttpClient> _client;\n\n        public TenPayApiRequest(ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3 = null, Action<HttpClient> setHeaderAction = null)\n        {\n            _tenpayV3Setting = senparcWeixinSettingForTenpayV3 ?? Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;\n            _setHeaderAction = setHeaderAction;\n            _client = GetOrCreateHttpClient(_tenpayV3Setting, _setHeaderAction);\n        }\n\n        private TenPayApiRequest(TenPayBrandApiCredentials brandApiCredentials)\n        {\n            _brandApiCredentials = brandApiCredentials ??\n                throw new ArgumentNullException(nameof(brandApiCredentials));\n            _client = BrandHttpClients.GetValue(_brandApiCredentials,\n                credentials => new Lazy<HttpClient>(\n                    () => CreateBrandHttpClient(credentials),\n                    LazyThreadSafetyMode.ExecutionAndPublication));\n        }\n\n        /// <summary>\n        /// 创建使用微信支付品牌 API 专用鉴权的请求实例。\n        /// </summary>\n        /// <param name=\"brandApiCredentials\">品牌 ID、品牌 API 证书和微信支付公钥凭据。</param>\n        /// <returns>使用 <c>WECHATPAY-BRAND-SHA256-RSA2048</c> 认证类型的请求实例。</returns>\n        public static TenPayApiRequest CreateForBrand(\n            TenPayBrandApiCredentials brandApiCredentials)\n        {\n            return new TenPayApiRequest(brandApiCredentials);\n        }\n\n        private static Lazy<HttpClient> GetOrCreateHttpClient(ISenparcWeixinSettingForTenpayV3 setting, Action<HttpClient> setHeaderAction)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs#L83-L119","documentation":"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.","triggerScenarios":"Constructing TenPayApiRequest via the internal/private overload with a null TenPayBrandApiCredentials, e.g. credentials failed to load from config or a factory returned null.","commonSituations":"Missing brand API credentials (证书/serial) in configuration; a DI or factory path passing an uninitialized credentials object.","solutions":["Provide a fully initialized TenPayBrandApiCredentials (cert key, serial number, etc.) before constructing the request","Guard with ArgumentNullException.ThrowIfNull at your own call site to fail earlier with clearer context","Verify brand credentials are loaded from configuration correctly"],"exampleFix":"// before\nvar req = new TenPayApiRequest((TenPayBrandApiCredentials)null);\n// after\nvar creds = new TenPayBrandApiCredentials { /* load cert + serial */ };\nvar req = new TenPayApiRequest(creds);","handlingStrategy":"try-catch","validationCode":"if (brandApiCredentials == null)\n    throw new InvalidOperationException(\"品牌 API 凭证未配置\");","typeGuard":null,"tryCatchPattern":"try { var req = new TenPayApiRequest(credentials); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"brandApiCredentials\") { log.Error(\"品牌 API 凭证为空\", ex); throw; }","preventionTips":["Load and validate brand credentials (serial + key) at startup, fail fast if missing","Keep credentials in configuration with schema checks, not hand-built objects","Cover the brand-credentials constructor path in a unit test"],"tags":["wechat-pay","null-argument","http-client"],"backgroundTag":"null-argument","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}