После некоторого расследования с помощью Reflector мы в конечном итоге обнаружили причину, по которой электронные письма не отправлялись (и почему они никогда не будут иметь значения независимо от того, что мы изменили в настройках)
Уведомления о проверке и истечении срока действия работают через комбинацию обработчика событий, определения задания таймера sharepoint и пользовательского списка, называемого страницами уведомлений / списком уведомлений. Основной порядок событий следующий:
- В процессе авторизации новой страницы контента пользователь выбирает отправку ему уведомления о проверке или истечении срока действия в определенный момент времени. Страница содержимого впоследствии регистрируется и публикуется.
- Обработчик события (ScheduledItemEventReceiver) запускается и проверяет, что рассматриваемый элемент является ScheduledItem и находится в процессе утверждения. Если это так, то он сообщит элементу о регистрации своего расписания (ScheduledItem.Schedule (...)).
- Этот процесс заботится о запланированных датах начала и окончания, указанных для элемента, обеспечивая его доступность в нужное время. Кроме того, следует добавить элемент в список уведомлений (http://[Site Имя] / Страницы уведомлений /).
- Задание таймера (NotificationJobDefinition) будет периодически запрашивать элементы в списке уведомлений и, если дата доставки прошла, отправит электронное письмо с уведомлением о проверке или истечении срока действия контакту страницы.
Так что все это звучит нормально и в теории должно работать отлично, но есть проблема. Чтобы добавить элемент в список уведомлений, метод ScheduledItem.Schedule вызывает метод HandleScheduling.
Метод HandleScheduling для PublishingPage (наследуется от ScheduledItem) будет вызывать UpdateNotificationList, который, в свою очередь, добавляет элемент в список уведомлений.
Метод HandleScheduling для базового класса ScheduledItem пуст.
Кажется, проблема в том, что класс ScheduledItemEventReceiver создает свои объекты как ScheduledItem (базовый класс), и поэтому всякий раз, когда он вызывает HandleScheduling, ничего не происходит. Вы можете перейти к списку уведомлений (/ Notification Pages / AllItems.aspx - требуются разрешения администратора семейства сайтов), и он полностью пуст.
В настоящее время у нас есть обходной путь. Мы разработали и развернули специальный приемник событий, который заменяет ScheduledItemEventReceiver. Он проверяет, является ли элемент страницей публикации, и если это так, использует некоторое отражение для непосредственного вызова метода UpdateNotificationList. После этого мы начали видеть элементы, добавляемые в список уведомлений, как и ожидалось.
public class ScheduledPageEventReceiver : SPItemEventReceiver
{
protected void HandleScheduling(PublishingPage page)
{
Type t = typeof(PublishingPage);
MethodInfo notificationMethod = t.GetMethod("UpdateNotificationList",BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
if (notificationMethod != null)
{
notificationMethod.Invoke(page, null);
}
}
public override void ItemUpdating(SPItemEventProperties properties)
{
if (properties == null)
{
throw new ArgumentNullException("properties");
}
if (properties.AfterProperties == null)
{
throw new ArgumentNullException("properties.AfterProperties");
}
object status = properties.AfterProperties["vti_doclibmodstat"];
if ((status != null) && (Convert.ToInt32(status, CultureInfo.InvariantCulture) == 0)) //Approved
{
using (SPWeb web = properties.OpenWeb())
{
SPListItem item = web.GetFile(properties.BeforeUrl).Item;
if (PublishingPage.IsPublishingPage(item) && PublishingPage.IsScheduledItem(item))
{
PublishingPage page = PublishingPage.GetPublishingPage(item);
HandleScheduling(page);
return;
}
}
}
}
}