ASP.NET Core Web API推送通知报错:注册推送系统句柄无效
推送通知失败排查:"The Push Notification System handle for the registration is invalid"错误分析
我正在通过ASP.NET Core Web API向Android和Apple设备推送通知,但多数时候推送失败,收到错误提示:
The Push Notification System handle for the registration is invalid
我无法理解该错误原因,项目中使用的是版本4.0.0的NotificationHub NuGet包,现将相关代码附上,恳请帮忙排查该问题。
public async static Task SendPushNotificationToDevice(HubNotification hubNotification) { if (hubNotification != null) { try { NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString (ConfigurationManager.AppSettings["HubConnectionString"], ConfigurationManager.AppSettings["HubName"], true); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; if (!string.IsNullOrEmpty(hubNotification.DeviceId) && !string.IsNullOrEmpty(hubNotification.DeviceType)) { // check if the already registered device var registationDescriptions = hub.GetRegistrationsByTagAsync(hubNotification.ToUserEmail, 100) .Result; foreach (var registrationDescription in registationDescriptions) { // We shouldn't have any extra registrations; delete if we do. hub.DeleteRegistrationAsync(registrationDescription); } // set message hubNotification.Message = string.Format(hubNotification.Message); if (!string.IsNullOrEmpty(hubNotification.Message)) { string jsonPayLoad = string.Empty; NotificationOutcome outcome; if (hubNotification.DeviceType.ToLower().Contains("android")) { var registeredNewDevice = hub.CreateGcmNativeRegistrationAsync( hubNotification.DeviceId.Replace("-", ""), new[]{hubNotification.ToUserEmail}) .Result; jsonPayLoad = "{ \"data\": " + "{ \"message\"" ": \"" " + hubNotification.Message.Trim() + "\"" "," + "\"ListId\"" ": \"" " + hubNotification.ListId + "\"" "," + "\"notificationType\"" ": \"" " + hubNotification.NotificationType + "\"" "," + "\"IsOwner\"" ": \"" " + hubNotification.IsOwner + "\"" "," + "\"ListName\"" ": \"" " + hubNotification.ListName + "\"" "," + "\"ListType\"" ": \"" " + hubNotification.ListType + "\"" "," + "\"badge\"" ": \"" " + hubNotification.badge + "\"" "," + "\"inProgress\"" ": \"" " + hubNotification.InProgress + "\"" "," + "\"headercolor\"" ": \"" " + hubNotification.ListHeaderColor + "\"" "," + "\"titlecolor\"" ": \"" " + hubNotification.ListHeaderTitleColor + "\"" "," + "\"sound\"" ":\"" " + hubNotification.Sound + "\"" "," + "\"userProfileId\"" ":\"" " + hubNotification.ToUserProfileId.ToString().Trim() + "\"" "," + "\"type\":\"sendfriend\"}}"; outcome = hub.SendGcmNativeNotificationAsync( jsonPayLoad, hubNotification.ToUserEmail) .Result; } else { hubNotification.Sound = hubNotification.Sound + ".caf"; var registeredNewDevice = hub.CreateAppleNativeRegistrationAsync( hubNotification.DeviceId.Replace("-", ""), new[]{hubNotification.ToUserEmail}) .Result; jsonPayLoad = "{ \"aps\": " + "{ \"alert\"" ": \"" " + hubNotification.Message.Trim() + "\"" "," + "\"ListId\"" ": \"" " + hubNotification.ListId + "\"" "," + "\"notificationType\"" ": \"" " + hubNotification.NotificationType + "\"" "," + "\"IsOwner\"" ": \"" " + hubNotification.IsOwner + "\"" "," + "\"ListName\"" ": \"" " + hubNotification.ListName + "\"" "," + "\"ListType\"" ": \"" " + hubNotification.ListType + "\"" "," + "\"badge\"" ": \"" " + hubNotification.badge + "\"" "," + "\"InProgress\"" ": \"" " + hubNotification.InProgress + "\"" "," + "\"headercolor\"" ": \"" " + hubNotification.ListHeaderColor + "\"" "," + "\"titlecolor\"" ": \"" " + hubNotification.ListHeaderTitleColor + "\"" "," + "\"sound\"" ":\"" " + hubNotification.Sound + "\"" "," + "\"userProfileId\"" ":\"" " + hubNotification.ToUserProfileId.ToString().Trim() + "\"" "," + "\"type\":\"sendfriend\"}}"; outcome = hub.SendAppleNativeNotificationAsync(jsonPayLoad, hubNotification.ToUserEmail) .Result; } // check the response if (outcome != null) { if (!((outcome.State == NotificationOutcomeState.Abandoned) || (outcome.State == NotificationOutcomeState.Unknown))) { // Message send successfully!! } } } } } catch (Exception ex) { // LogError(ex.Message, "SendPushNotificationToDevice"); } } }
核心错误原因及修复方案
1. 设备令牌处理错误
Apple的APNS设备令牌原生包含连字符,是合法格式,代码中统一执行Replace("-", "")会直接破坏APNS令牌的有效性,触发"无效注册句柄"错误。
修复:仅针对Android设备处理令牌(若原始令牌确实带连字符,通常FCM令牌无连字符):
string deviceToken = hubNotification.DeviceType.ToLower().Contains("android") ? hubNotification.DeviceId.Replace("-", "") : hubNotification.DeviceId;
2. 异步代码滥用.Result
所有异步方法用.Result阻塞调用,容易引发死锁或未捕获的异常,导致注册/推送流程中断,间接引发注册状态异常。
修复:替换所有.Result为await,保持方法异步特性:
var registationDescriptions = await hub.GetRegistrationsByTagAsync(hubNotification.ToUserEmail, 100); foreach (var registrationDescription in registationDescriptions) { await hub.DeleteRegistrationAsync(registrationDescription); } // 其他Create/Update/Send类异步调用同理替换为await
3. 注册逻辑缺陷
每次推送前删除用户所有注册再重建,存在时间窗口问题,且频繁删除重建会导致Notification Hub注册状态不一致,引发无效句柄错误。
修复:先查询设备是否已注册,存在则更新,不存在再创建:
var existingRegistrations = await hub.GetRegistrationsByChannelAsync(deviceToken, 100); if (existingRegistrations.Any()) { var existingReg = existingRegistrations.First(); existingReg.Tags = new HashSet<string> { hubNotification.ToUserEmail }; await hub.UpdateRegistrationAsync(existingReg); } else { if (hubNotification.DeviceType.ToLower().Contains("android")) { await hub.CreateGcmNativeRegistrationAsync(deviceToken, new[]{hubNotification.ToUserEmail}); } else { await hub.CreateAppleNativeRegistrationAsync(deviceToken, new[]{hubNotification.ToUserEmail}); } }
4. 手动拼接JSON语法错误
代码中手动拼接JSON存在引号闭合、格式错误等问题,生成的Payload会被APNS/FCM拒绝,间接触发注册无效错误。
修复:使用强类型类+JSON序列化生成Payload:
// 定义Android Payload类 public class AndroidPayload { public AndroidData data { get; set; } } public class AndroidData { public string message { get; set; } public string ListId { get; set; } // 补充其他所需字段 } // 序列化生成JSON var payload = new AndroidPayload { data = new AndroidData { message = hubNotification.Message.Trim(), ListId = hubNotification.ListId // 赋值其他字段 } }; string jsonPayLoad = JsonConvert.SerializeObject(payload);
5. 异常捕获不完整
catch块仅记录消息,丢失堆栈和内部异常信息,无法定位具体失败环节。
修复:记录完整异常信息:
catch (Exception ex) { LogError($"推送失败: {ex.Message}, 堆栈: {ex.StackTrace}, 内部异常: {ex.InnerException?.Message}", "SendPushNotificationToDevice"); }
内容的提问来源于stack exchange,提问作者pratapsingh845
相关产品推荐
相关产品推荐

