{"record":{"id":"c434d3d66d4bfe5e","repo":"JeffreySu/WeiXinMPSDK","slug":"corpid","errorCode":null,"errorMessage":"CorpId 不能为空。","messagePattern":"CorpId 不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/Containers/AccessTokenContainer.cs","lineNumber":389,"sourceCode":"        /// <summary>\n        /// 使用稳定 registrationKey 和外部凭据提供器注册企业微信 AccessToken。\n        /// 自动重注册委托不捕获明文 CorpSecret；调用 API 时使用返回的 registrationKey 作为 AppKey。\n        /// </summary>\n        public static async Task RegisterWithCredentialProviderAsync(\n            string registrationKey,\n            string corpId,\n            IWeixinCredentialProvider credentialProvider,\n            string name = null,\n            CancellationToken cancellationToken = default)\n        {\n            if (string.IsNullOrWhiteSpace(registrationKey))\n            {\n                throw new ArgumentException(\"registrationKey 不能为空。\", nameof(registrationKey));\n            }\n\n            if (string.IsNullOrWhiteSpace(corpId))\n            {\n                throw new ArgumentException(\"CorpId 不能为空。\", nameof(corpId));\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(registrationKey, token).ConfigureAwait(false);\n                if (string.IsNullOrWhiteSpace(secret))\n                {\n                    throw new InvalidOperationException(\"凭据提供器返回了空 CorpSecret。\");\n                }\n\n                var bag = new AccessTokenBag\n                {\n                    Name = name,","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/Containers/AccessTokenContainer.cs#L371-L407","documentation":"AccessTokenContainer.RegisterWithCredentialProviderAsync throws ArgumentException(\"CorpId 不能为空。\") when the corpId argument is null, empty, or whitespace. CorpId identifies the WeChat Work (企业微信) corporation whose access token is being registered; without it the cache key and API calls are meaningless. It is validated right after registrationKey, before the credential provider is touched.","triggerScenarios":"Calling RegisterWithCredentialProviderAsync(regKey, null, provider) or with \"\" / whitespace corpId — e.g. corpId read from appsettings/env that is unset.","commonSituations":"Missing CorpId in configuration files after environment migration; multi-tenant setups where the tenant's corpId is not yet provisioned; copy-paste of sample code with empty placeholder.","solutions":["Pass the real WeChat Work CorpId string, e.g. \"wx5ac3f21a\" / your 企业ID from the WeChat Work admin console.","Validate configuration at startup: throw early if string.IsNullOrWhiteSpace(config.CorpId).","If multi-tenant, ensure the tenant lookup resolves a corpId before registering the token."],"exampleFix":"// before\nawait AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, tenant.CorpId, provider); // CorpId null\n// after\nif (string.IsNullOrWhiteSpace(tenant.CorpId)) throw new InvalidOperationException($\"Tenant {tenant.Id} has no CorpId configured.\");\nawait AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, tenant.CorpId, provider);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(corpId))\n    throw new InvalidOperationException(\"CorpId (企业ID) is missing from configuration.\");\nawait AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, corpId, provider);","typeGuard":"bool IsValidCorpId(string corpId) => !string.IsNullOrWhiteSpace(corpId);","tryCatchPattern":"try\n{\n    await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, corpId, provider);\n}\ncatch (ArgumentException ex) when (ex.ParamName == \"corpId\")\n{\n    log.LogCritical(\"CorpId is empty; cannot register access token.\");\n    throw;\n}","preventionTips":["Store CorpId in configuration with startup validation (IOptions + ValidateDataAnnotations).","For multi-tenant apps, verify tenant provisioning includes a non-empty CorpId.","Copy CorpId exactly from the WeChat Work admin console; trim whitespace on read."],"tags":["argument-validation","corpid","registration"],"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"}