Stack Overflow Exception when creating a new notification

I have a custom notification type, but getting a stack overflow exception when it triggers...

Parents Reply Children
  •  public class SessionPreLearningMissing : IPlugin, INotificationType, IRecurringEvolutionJobPlugin
        {
            #region Public Members
            public string SESSION_NOTIFICATIONS_FLAG = "RUN_SESSION_NOTIFICATIONS";
            #endregion
            #region Private Members
            private INotificationController _notificationController;
            #endregion
            #region IPlugin Members
            public string Name => "Hearing First - Session PreLearning Missing Notifications";
    
            public string Description => "Notification plugins for when the session is over, but learners still have pre-learning to complete";
    
    
    
            public void Initialize()
            {
               
            }
            #endregion
            #region INotificationType Plugin Members
            public string NotificationTypeName => "Session PreLearning Missing Notification Type";
    
            public string NotificationTypeDescription => "Notification type for missing pre-learning";
    
            public string NotificationTypeCategory => "Hearing First";
    
            public Guid NotificationTypeId => Guid.Parse("BC9C1D78-B680-42EE-A35F-0BC99B8B3F02");
    
            public bool IsCacheable => false;
    
            public bool VaryCacheByUser => false;
    
            public bool CanDeleteNotification(Guid notificationId, int userId)
            {
                return true;
            }
    
            public string GetMessage(Guid notificationId, [Documentation("Target", OptionsType = typeof(NotificationTarget))] string target)
            {
                var notification = Apis.Get<INotifications>().Get(notificationId);
                var session = HearingFirst.LearningExperience.Components.Sessions.Get(notification.ContentId.Value);
                var course = HearingFirst.LearningExperience.Components.Courses.Get(session.CourseId);
    
                switch (target)
                {
                    case "Html":
                    case "ShortText":
                    case "Text":
                    default: return String.Format("You have missing Session {0} pre-learning requirements in {1}", session.SortOrder.ToString(), course.Name);
                }
            }
    
            public string GetTargetUrl(Guid notificationId)
            {
                var notification = Apis.Get<INotifications>().Get(notificationId);
                var session = HearingFirst.LearningExperience.Components.Sessions.Get(notification.ContentId.Value);
                var course = HearingFirst.LearningExperience.Components.Courses.Get(session.CourseId);
                return course.Url;
            }
    
            public void SetController(INotificationController controller)
            {
                _notificationController = controller;
            }
            #endregion
            #region IRecurringEvolutionJobPlugin Members
            public Guid JobTypeId => Guid.Parse("636B5D02-809B-4AB1-8A63-01F2766B2BBB");
    
            public JobSchedule DefaultSchedule => JobSchedule.Daily();
    
            public JobContext SupportedContext => JobContext.Service;
            public void Execute(JobData jobData)
            {
                // Get all courses if open and datetime.now > startdate && less than close date + 5 days
                //Get the courses that arent finished yet
    
                var courses = HearingFirst.LearningExperience.Components.Courses.List();
                var activeCourses = (from c in courses where
                                     c.StartDate < DateTime.Now
                                     && c.EndDate.AddDays(5) > DateTime.Now select c).ToList();
    
                foreach(var course in activeCourses)
                {
                    var registrants = HearingFirst.LearningExperience.Components.Courses.GetCourseRoster(course.GroupId);
                    var sessions = HearingFirst.LearningExperience.Components.Sessions.ListCourseSessions(course.Id);
                    
                    // Loop through the sessions and determine if the session is flagged for notifications.
                    foreach(var session in sessions)
                    {
                        var flag = HearingFirst.ContentAttributes.Components.ContentAttributes.Get(session.ContentId, HearingFirst.LearningExperience.Components.Sessions.CONTENT_TYPE_ID, this.SESSION_NOTIFICATIONS_FLAG);
                        if(flag != null && flag.Value.Equals("1"))
                        {                        
                            foreach(var registrant in registrants)
                            {
                                try
                                {
                                    var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Username = registrant.Username });
                                    var requirementsRemaining = Components.CourseRequirements.RemainingPreLearningSessionRequirementCount(user.Id.Value, course.Id, session.Id);
                                    var adobeAttended = Components.CourseRequirements.TotalAdobeSessionRequirementsMet(user.Id.Value, course.Id, session.Id);
                                    var totalAdobe = Components.CourseRequirements.TotalAdobeSessionRequirements(course.Id, session.Id);
                                    if (requirementsRemaining > 0 && adobeAttended == totalAdobe)
                                    {
                                        _notificationController.CreateUpdate(new NotificationCreateUpdateOptions
                                        {
                                            ContentId = session.ContentId,
                                            ContentTypeId = session.ContentTypeId, 
                                            UserId = user.Id.Value,
                                            LastUpdate = DateTime.UtcNow
                                        });
                                    }
                                }
                                catch(Exception ex) {
                                    var exc = ex;
    
                                }
                            }
                            
                            // Reset the session flag to "0" meaning the notifications have been sent for this session.
                            HearingFirst.ContentAttributes.Components.ContentAttributes.CreateOrUpdate(
                                new ContentAttributes.Entities.ContentAttribute {
                                    ContentId = session.ContentId,
                                    ContentTypeId = HearingFirst.LearningExperience.Components.Sessions.CONTENT_TYPE_ID,
                                    Key = this.SESSION_NOTIFICATIONS_FLAG,
                                    Value = "0",
                                });
                        }   
                    }
                }
                
                        }
            #endregion
        }