{"record":{"id":"63763b2f57711253","repo":"JeffreySu/WeiXinMPSDK","slug":"wxopenappid-0-accesstokencontainer-register","errorCode":null,"errorMessage":"此wxOpenAppId（{0}）尚未注册，请先使用AccessTokenContainer.Register完成注册（全局执行一次即可）！","messagePattern":"此wxOpenAppId（(.+?)）尚未注册，请先使用AccessTokenContainer\\.Register完成注册（全局执行一次即可）！","errorType":"exception","errorClass":"UnRegisterAppIdException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs","lineNumber":130,"sourceCode":"        /// <param name=\"wxOpenAppId\"></param>\n        /// <param name=\"getNewToken\">是否强制重新获取新的Token</param>\n        /// <returns></returns>\n        public static string GetAccessToken(string wxOpenAppId, bool getNewToken = false)\n        {\n            return GetAccessTokenResult(wxOpenAppId, getNewToken).access_token;\n        }\n\n        /// <summary>\n        /// 获取可用AccessTokenResult对象\n        /// </summary>\n        /// <param name=\"wxOpenAppId\"></param>\n        /// <param name=\"getNewToken\">是否强制重新获取新的Token</param>\n        /// <returns></returns>\n        public static AccessTokenResult GetAccessTokenResult(string wxOpenAppId, bool getNewToken = false)\n        {\n            if (!CheckRegistered(wxOpenAppId))\n            {\n                throw new UnRegisterAppIdException(wxOpenAppId, string.Format(\"此wxOpenAppId（{0}）尚未注册，请先使用AccessTokenContainer.Register完成注册（全局执行一次即可）！\", wxOpenAppId));\n            }\n\n            var accessTokenBag = TryGetItem(wxOpenAppId);\n\n            using (Cache.BeginCacheLock(LockResourceName, wxOpenAppId))//同步锁\n            {\n                accessTokenBag = TryGetItem(wxOpenAppId);//获锁后重新读取，避免使用分布式缓存中的旧副本重复刷新\n                if (getNewToken || accessTokenBag.AccessTokenExpireTime <= SystemTime.Now)\n                {\n                    //已过期，重新获取\n                    accessTokenBag.AccessTokenResult = CommonApi.GetToken(accessTokenBag.WxOpenAppId, accessTokenBag.WxOpenAppSecret);\n                    accessTokenBag.AccessTokenExpireTime = ApiUtility.GetExpireTime(accessTokenBag.AccessTokenResult.expires_in);\n                    Update(accessTokenBag, null);//更新到缓存\n                }\n            }\n            return accessTokenBag.AccessTokenResult;\n        }\n","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs#L112-L148","documentation":"AccessTokenContainer.GetAccessTokenResult throws UnRegisterAppIdException when the given wxOpenAppId has not been registered via AccessTokenContainer.Register. The SDK stores access tokens in a container keyed by AppId; requesting a token for an unregistered AppId is treated as a configuration error, not an API error.","triggerScenarios":"Calling GetAccessTokenResult/GetAccessToken (or any API relying on it) with an AppId that was never passed to AccessTokenContainer.Register(appId, appSecret) at application startup, or after a cache flush/restart that lost registration state.","commonSituations":"Multiple Mini Programs configured but only some registered; Register call placed in a code path that never executes (e.g. guarded by environment check); scaled-out instances where only one instance ran the registration; AppId typo mismatch between Register and the consumer.","solutions":["Call AccessTokenContainer.Register(wxOpenAppId, wxOpenAppSecret) once during application startup","Ensure the registered AppId string exactly matches the one requested (no typos/casing)","Use Config.SenparcWeixinSetting bindings so Register and consumers read the same settings","Verify Register actually runs on every deployment/instance (global.asax/Startup), not conditionally"],"exampleFix":"// before\nvar token = AccessTokenContainer.GetAccessTokenResult(appId); // appId never registered\n// after\n// Startup:\nAccessTokenContainer.Register(appId, appSecret, \"MiniProgram\");\n// Usage:\nvar token = AccessTokenContainer.GetAccessTokenResult(appId);","handlingStrategy":"try-catch","validationCode":"if (!AccessTokenContainer.CheckRegistered(wxOpenAppId)) AccessTokenContainer.Register(wxOpenAppId, appSecret);","typeGuard":null,"tryCatchPattern":"try { return AccessTokenContainer.GetAccessTokenResult(appId); }\ncatch (UnRegisterAppIdException ex) { logger.LogError(ex, \"AppId {AppId} not registered — call AccessTokenContainer.Register at startup\", appId); throw; }","preventionTips":["Call AccessTokenContainer.Register in application startup (every instance)","Use SenparcWeixinSetting so registration and consumption share one source of truth","Confirm the exact AppId string matches between Register and usage"],"tags":["wxopen","access-token","unregistered-appid","initialization"],"backgroundTag":"missing-required-config","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"}