{"record":{"id":"57034d666b27a98a","repo":"JeffreySu/WeiXinMPSDK","slug":"appid-jsapiticketcontainer-register","errorCode":null,"errorMessage":"此appId尚未注册，请先使用JsApiTicketContainer.Register完成注册（全局执行一次即可）！","messagePattern":"此appId尚未注册，请先使用JsApiTicketContainer\\.Register完成注册（全局执行一次即可）！","errorType":"exception","errorClass":"UnRegisterAppIdException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.MP/Senparc.Weixin.MP/Containers/JsApiTicketContainer.cs","lineNumber":182,"sourceCode":"        /// <param name=\"appId\"></param>\n        /// <param name=\"getNewTicket\">是否强制重新获取新的Ticket</param>\n        /// <returns></returns>\n        public static string GetJsApiTicket(string appId, bool getNewTicket = false)\n        {\n            return GetJsApiTicketResult(appId, getNewTicket).ticket;\n        }\n\n        /// <summary>\n        /// 获取可用Ticket\n        /// </summary>\n        /// <param name=\"appId\"></param>\n        /// <param name=\"getNewTicket\">是否强制重新获取新的Ticket</param>\n        /// <returns></returns>\n        public static JsApiTicketResult GetJsApiTicketResult(string appId, bool getNewTicket = false)\n        {\n            if (!CheckRegistered(appId))\n            {\n                throw new UnRegisterAppIdException(null, \"此appId尚未注册，请先使用JsApiTicketContainer.Register完成注册（全局执行一次即可）！\");\n            }\n\n            var jsApiTicketBag = TryGetItem(appId);\n            using (Cache.BeginCacheLock(LockResourceName, appId))//同步锁\n            {\n                jsApiTicketBag = TryGetItem(appId);//获锁后重新读取并二次检查过期状态\n                if (getNewTicket || jsApiTicketBag.JsApiTicketExpireTime <= SystemTime.Now)\n                {\n                    //已过期，重新获取\n                    jsApiTicketBag.JsApiTicketResult = CommonApi.GetTicket(jsApiTicketBag.AppId, jsApiTicketBag.AppSecret);\n                    jsApiTicketBag.JsApiTicketExpireTime = ApiUtility.GetExpireTime(jsApiTicketBag.JsApiTicketResult.expires_in);\n                    Update(jsApiTicketBag, null);\n                }\n            }\n            return jsApiTicketBag.JsApiTicketResult;\n        }\n\n        #endregion","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.MP/Senparc.Weixin.MP/Containers/JsApiTicketContainer.cs#L164-L200","documentation":"GetJsApiTicketResult throws UnRegisterAppIdException when CheckRegistered(appId) reports the appId is not registered in JsApiTicketContainer. JS-API tickets use their own container, so an appId registered only in AccessTokenContainer is still unregistered here; a separate JsApiTicketContainer.Register call is required.","triggerScenarios":"Calling JsApiTicketContainer.GetJsApiTicket(appId) or GetJsApiTicketResult(appId) without a prior JsApiTicketContainer.Register(appId, appSecret) for that appId.","commonSituations":"Developer assumes the AccessToken registration covers tickets (it does not); ticket registration call accidentally removed in a refactor; new appId added to token config but not the ticket registration list; container cache reset on restart with memory cache.","solutions":["Call JsApiTicketContainer.Register(appId, appSecret) once at startup for every appId needing JS-API tickets.","Register in BOTH containers if you need both access tokens and tickets.","Ensure the appId matches exactly the one used at lookup.","If tickets are only needed later, wrap retrieval with a registered-check or register lazily on first use."],"exampleFix":"// before\nvar ticket = JsApiTicketContainer.GetJsApiTicket(appId); // throws: only AccessToken registered\n// after\nAccessTokenContainer.Register(appId, appSecret);\nJsApiTicketContainer.Register(appId, appSecret); // required separately\nvar ticket = JsApiTicketContainer.GetJsApiTicket(appId);","handlingStrategy":"try-catch","validationCode":"if (!JsApiTicketContainer.CheckRegistered(appId))\n{\n    JsApiTicketContainer.Register(appId, appSecret);\n}","typeGuard":"bool IsTicketRegistered(string appId) => JsApiTicketContainer.CheckRegistered(appId);","tryCatchPattern":"try\n{\n    var ticket = JsApiTicketContainer.GetJsApiTicket(appId);\n}\ncatch (UnRegisterAppIdException ex)\n{\n    _logger.LogError(ex, \"appId {AppId} missing from JsApiTicketContainer registration.\", appId);\n    JsApiTicketContainer.Register(appId, _secrets.Get(appId));\n}","preventionTips":["Remember ticket registration is separate from token registration; register both together.","Group all container registrations in one startup helper so none are forgotten.","Add the ticket container check to startup health checks.","Re-run registrations on application start when using memory cache."],"tags":["csharp","weixin","jsapi-ticket","unregistered-appid"],"backgroundTag":"unregistered-appid","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"}