JeffreySu/WeiXinMPSDK · error · UnRegisterAppIdException
此wxOpenAppId(…
Error message
此wxOpenAppId({0})尚未注册,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)! What it means
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.
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
Example fix
// before var token = AccessTokenContainer.GetAccessTokenResult(appId); // appId never registered // after // Startup: AccessTokenContainer.Register(appId, appSecret, "MiniProgram"); // Usage: var token = AccessTokenContainer.GetAccessTokenResult(appId);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!AccessTokenContainer.CheckRegistered(wxOpenAppId)) AccessTokenContainer.Register(wxOpenAppId, appSecret);
Try / catch
try { return AccessTokenContainer.GetAccessTokenResult(appId); }
catch (UnRegisterAppIdException ex) { logger.LogError(ex, "AppId {AppId} not registered — call AccessTokenContainer.Register at startup", appId); throw; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- AppId 不能为空。
- 微信请求发生错误!错误代码: ,说明:
- 微信请求发生错误(CommonApi.GetToken)!错误代码:
- 微信请求发生错误(CommonApi.GetStableAccessToken)!错误代码:
- 微信请求发生错误(CommonApi.GetStableAccessTokenAsync)!错误代码:
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/63763b2f57711253.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs:130
/// <param name="wxOpenAppId"></param>
/// <param name="getNewToken">是否强制重新获取新的Token</param>
/// <returns></returns>
public static string GetAccessToken(string wxOpenAppId, bool getNewToken = false)
{
return GetAccessTokenResult(wxOpenAppId, getNewToken).access_token;
}
/// <summary>
/// 获取可用AccessTokenResult对象
/// </summary>
/// <param name="wxOpenAppId"></param>
/// <param name="getNewToken">是否强制重新获取新的Token</param>
/// <returns></returns>
public static AccessTokenResult GetAccessTokenResult(string wxOpenAppId, bool getNewToken = false)
{
if (!CheckRegistered(wxOpenAppId))
{
throw new UnRegisterAppIdException(wxOpenAppId, string.Format("此wxOpenAppId({0})尚未注册,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!", wxOpenAppId));
}
var accessTokenBag = TryGetItem(wxOpenAppId);
using (Cache.BeginCacheLock(LockResourceName, wxOpenAppId))//同步锁
{
accessTokenBag = TryGetItem(wxOpenAppId);//获锁后重新读取,避免使用分布式缓存中的旧副本重复刷新
if (getNewToken || accessTokenBag.AccessTokenExpireTime <= SystemTime.Now)
{
//已过期,重新获取
accessTokenBag.AccessTokenResult = CommonApi.GetToken(accessTokenBag.WxOpenAppId, accessTokenBag.WxOpenAppSecret);
accessTokenBag.AccessTokenExpireTime = ApiUtility.GetExpireTime(accessTokenBag.AccessTokenResult.expires_in);
Update(accessTokenBag, null);//更新到缓存
}
}
return accessTokenBag.AccessTokenResult;
}
View on GitHub (pinned to be573f6f94)