JeffreySu/WeiXinMPSDK · error · UnRegisterAppIdException
此appId尚未注册,请先使用JsApiTicketContainer.Register完成注册(全局执行一次即可)!
Error message
此appId尚未注册,请先使用JsApiTicketContainer.Register完成注册(全局执行一次即可)!
What it means
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.
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.
Example fix
// before var ticket = JsApiTicketContainer.GetJsApiTicket(appId); // throws: only AccessToken registered // after AccessTokenContainer.Register(appId, appSecret); JsApiTicketContainer.Register(appId, appSecret); // required separately var ticket = JsApiTicketContainer.GetJsApiTicket(appId);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!JsApiTicketContainer.CheckRegistered(appId))
{
JsApiTicketContainer.Register(appId, appSecret);
} Type guard
bool IsTicketRegistered(string appId) => JsApiTicketContainer.CheckRegistered(appId);
Try / catch
try
{
var ticket = JsApiTicketContainer.GetJsApiTicket(appId);
}
catch (UnRegisterAppIdException ex)
{
_logger.LogError(ex, "appId {AppId} missing from JsApiTicketContainer registration.", appId);
JsApiTicketContainer.Register(appId, _secrets.Get(appId));
} Prevention
- 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.
When it happens
Trigger: Calling JsApiTicketContainer.GetJsApiTicket(appId) or GetJsApiTicketResult(appId) without a prior JsApiTicketContainer.Register(appId, appSecret) for that appId.
Common situations: 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.
Related errors
- 此appId(…
- 此 appId code 尚未注册,请先使用 OAuthAccessTokenContainer.Register…
- 注册委托容量必须大于 0。
- 当前已有 个注册委托,不能把容量降低到 。
- 注册委托数量已达到上限 ,请先注销不再使用的账号或提高 MaximumCount。
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/57034d666b27a98a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.MP/Senparc.Weixin.MP/Containers/JsApiTicketContainer.cs:182
/// <param name="appId"></param>
/// <param name="getNewTicket">是否强制重新获取新的Ticket</param>
/// <returns></returns>
public static string GetJsApiTicket(string appId, bool getNewTicket = false)
{
return GetJsApiTicketResult(appId, getNewTicket).ticket;
}
/// <summary>
/// 获取可用Ticket
/// </summary>
/// <param name="appId"></param>
/// <param name="getNewTicket">是否强制重新获取新的Ticket</param>
/// <returns></returns>
public static JsApiTicketResult GetJsApiTicketResult(string appId, bool getNewTicket = false)
{
if (!CheckRegistered(appId))
{
throw new UnRegisterAppIdException(null, "此appId尚未注册,请先使用JsApiTicketContainer.Register完成注册(全局执行一次即可)!");
}
var jsApiTicketBag = TryGetItem(appId);
using (Cache.BeginCacheLock(LockResourceName, appId))//同步锁
{
jsApiTicketBag = TryGetItem(appId);//获锁后重新读取并二次检查过期状态
if (getNewTicket || jsApiTicketBag.JsApiTicketExpireTime <= SystemTime.Now)
{
//已过期,重新获取
jsApiTicketBag.JsApiTicketResult = CommonApi.GetTicket(jsApiTicketBag.AppId, jsApiTicketBag.AppSecret);
jsApiTicketBag.JsApiTicketExpireTime = ApiUtility.GetExpireTime(jsApiTicketBag.JsApiTicketResult.expires_in);
Update(jsApiTicketBag, null);
}
}
return jsApiTicketBag.JsApiTicketResult;
}
#endregionView on GitHub (pinned to be573f6f94)