{"record":{"id":"79dabb1cdf32f2f6","repo":"JeffreySu/WeiXinMPSDK","slug":"getcomponentverifyticketfunc","errorCode":null,"errorMessage":"GetComponentVerifyTicketFunc必须在注册时提供！","messagePattern":"GetComponentVerifyTicketFunc必须在注册时提供！","errorType":"exception","errorClass":"WeixinOpenException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Open/Senparc.Weixin.Open/Containers/ComponentContainer.cs","lineNumber":273,"sourceCode":"        /// <param name=\"getNewToken\"></param>\n        /// <returns>如果不存在，则返回null</returns>\n        public static string TryGetComponentVerifyTicket(string componentAppId, bool getNewToken = false)\n        {\n            if (!CheckRegistered(componentAppId))\n            {\n                throw new WeixinOpenException(UN_REGISTER_ALERT);\n            }\n\n            var bag = TryGetItem(componentAppId);\n            using (Cache.BeginCacheLock(LockResourceName + \".TryGetComponentVerifyTicket\", componentAppId))\n            {\n                bag = TryGetItem(componentAppId);//获锁后重新读取并二次检查过期状态\n                var componentVerifyTicket = bag.ComponentVerifyTicket;\n                if (getNewToken || componentVerifyTicket == default(string) || bag.ComponentVerifyTicketExpireTime < SystemTime.Now)\n                {\n                    if (GetComponentVerifyTicketFunc == null)\n                    {\n                        throw new WeixinOpenException(\"GetComponentVerifyTicketFunc必须在注册时提供！\", bag);\n                    }\n                    componentVerifyTicket = GetComponentVerifyTicketFunc(componentAppId).ConfigureAwait(false).GetAwaiter().GetResult(); //获取最新的componentVerifyTicket\n                    bag.ComponentVerifyTicket = componentVerifyTicket;\n                    bag.ComponentVerifyTicketExpireTime = ApiUtility.GetExpireTime(COMPONENT_VERIFY_TICKET_UPDATE_MINUTES * 60);\n                    Update(bag, null);//更新到缓存\n                }\n                return componentVerifyTicket;\n            }\n        }\n\n        /// <summary>\n        /// 更新ComponentVerifyTicket信息\n        /// </summary>\n        /// <param name=\"componentAppId\"></param>\n        /// <param name=\"componentVerifyTicket\"></param>\n        public static void UpdateComponentVerifyTicket(string componentAppId, string componentVerifyTicket)\n        {\n            Update(componentAppId, bag =>","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Open/Senparc.Weixin.Open/Containers/ComponentContainer.cs#L255-L291","documentation":"When the cached component_verify_ticket is missing or expired, TryGetComponentVerifyTicket needs a delegate GetComponentVerifyTicketFunc (supplied at ComponentContainer.Register) to fetch a fresh one. If that delegate is null, it throws WeixinOpenException requiring the func to be provided at registration time.","triggerScenarios":"ComponentContainer.Register was called without passing GetComponentVerifyTicketFunc, and then TryGetComponentVerifyTicket ran with getNewToken=true or with an expired/absent ticket.","commonSituations":"Registration overload used that omits the func; code migrated to a new container API where the func parameter was dropped; ticket expired between WeChat pushes (WeChat pushes a ticket every 10 minutes) and no fallback existed.","solutions":["Pass a GetComponentVerifyTicketFunc when calling ComponentContainer.Register; it should return the latest component_verify_ticket received from WeChat's push.","Persist the latest ticket (from the push event handler) in your own storage so the func can retrieve it.","Force an immediate WeChat push (e.g. re-authorize) to obtain a fresh ticket if none exists yet.","Verify the func is not overwritten to null by later re-registration code."],"exampleFix":"// before\nComponentContainer.Register(componentAppId, componentSecret);\n// after\nComponentContainer.Register(componentAppId, componentSecret,\n    async appId => await myTicketStore.GetLatestTicketAsync(appId));","handlingStrategy":"validation","validationCode":"// ensure the func is set at registration time\nComponentContainer.Register(componentAppId, componentSecret,\n    appId => Task.FromResult(ticketStore.GetLatestTicket(appId)));","typeGuard":null,"tryCatchPattern":"try { ticket = ComponentContainer.TryGetComponentVerifyTicket(componentAppId, getNewToken: true); }\ncatch (WeixinOpenException ex) { logger.Error(ex, \"GetComponentVerifyTicketFunc missing\"); throw; }","preventionTips":["Always pass GetComponentVerifyTicketFunc when registering","Persist tickets received from WeChat's push events","Know the ticket refresh cycle (~10 minutes)"],"tags":["weixin-open","container","missing-delegate","component-verify-ticket"],"backgroundTag":"missing-required-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"}