{"record":{"id":"5f0056723c88a73b","repo":"JeffreySu/WeiXinMPSDK","slug":"appid-5f0056","errorCode":null,"errorMessage":"AppId 不能为空。","messagePattern":"AppId 不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs","lineNumber":204,"sourceCode":"                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].WxOpenAppId = wxOpenAppId;\n                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].WxOpenAppSecret = wxOpenAppSecret;\n            }\n\n            await Task.WhenAll(new[] { registerTask }).ConfigureAwait(false);//等待所有任务完成\n        }\n\n        /// <summary>\n        /// 使用外部凭据提供器注册小程序 AccessToken，自动重注册委托不长期捕获明文 AppSecret。\n        /// </summary>\n        public static async Task RegisterWithCredentialProviderAsync(\n            string wxOpenAppId,\n            IWeixinCredentialProvider credentialProvider,\n            string name = null,\n            CancellationToken cancellationToken = default)\n        {\n            if (string.IsNullOrWhiteSpace(wxOpenAppId))\n            {\n                throw new ArgumentException(\"AppId 不能为空。\", nameof(wxOpenAppId));\n            }\n\n            if (credentialProvider == null)\n            {\n                throw new ArgumentNullException(nameof(credentialProvider));\n            }\n\n            async Task<AccessTokenBag> RegisterCoreAsync(CancellationToken token)\n            {\n                var secret = await credentialProvider.GetSecretAsync(wxOpenAppId, token).ConfigureAwait(false);\n                if (string.IsNullOrWhiteSpace(secret))\n                {\n                    throw new InvalidOperationException(\"凭据提供器返回了空 AppSecret。\");\n                }\n\n                var bag = new AccessTokenBag\n                {\n                    Name = name,","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs#L186-L222","documentation":"AccessTokenContainer.RegisterWithCredentialProviderAsync validates wxOpenAppId and throws ArgumentException ('AppId 不能为空。') when it is null or whitespace. Registration is the prerequisite for token management, so an empty AppId is rejected before any credential lookup happens.","triggerScenarios":"Calling RegisterWithCredentialProviderAsync with a null/empty wxOpenAppId, usually from configuration that was not populated (missing appsettings entry, unset env var) or a DI-bound settings object with a default empty string.","commonSituations":"New environment (staging/prod) missing the Mini Program AppId; config section renamed; credentials provided via IWeixinCredentialProvider but the AppId list itself is empty.","solutions":["Ensure the wxOpenAppId value is set in configuration before calling RegisterWithCredentialProviderAsync","Fail fast at startup: enumerate required settings and throw a descriptive error if any is blank","Check that the credential provider's AppId list is correctly wired when registering multiple apps"],"exampleFix":"// before\nawait AccessTokenContainer.RegisterWithCredentialProviderAsync(settings.WxOpenAppId, credentialProvider); // may be empty\n// after\nif (string.IsNullOrWhiteSpace(settings.WxOpenAppId)) throw new InvalidOperationException(\"WxOpenAppId missing from configuration\");\nawait AccessTokenContainer.RegisterWithCredentialProviderAsync(settings.WxOpenAppId, credentialProvider);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(wxOpenAppId)) throw new InvalidOperationException(\"wxOpenAppId must be provided before token registration\");","typeGuard":"bool IsValidAppId(string appId) => !string.IsNullOrWhiteSpace(appId);","tryCatchPattern":"try { await AccessTokenContainer.RegisterWithCredentialProviderAsync(appId, credentialProvider); }\ncatch (ArgumentException ex) { logger.LogCritical(ex, \"Cannot register tokens: AppId empty\"); throw; }","preventionTips":["Validate all WeChat settings (AppId/Secret) before the registration step in Startup","Fail fast on missing config keys with a descriptive startup error","Keep environment-specific config files (appsettings.Production.json) in sync with required keys"],"tags":["wxopen","appid","access-token","empty-argument"],"backgroundTag":"empty-required-field","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"}