То, что вы слышали правильно: ItemAdded будет срабатывать до завершения метаданных, потому что в библиотеке документов ItemAdded срабатывает при первой загрузке документа, а не при заполнении формы.
Я думаю, что наиболее плавным вариантом является использование рабочего процесса, который запускается при создании элемента в библиотеке документов. В частности, на основе кода с использованием Visual Studio 2008, если он у вас есть. Общее пошаговое руководство по созданию рабочих процессов с использованием Visual Studio 2008 можно найти здесь: Обработка рабочих процессов SharePoint с помощью Visual Studio . Из этой статьи я узнал, в первую очередь, как создавать рабочие процессы, поэтому я надеюсь, что она поможет вам так же, как и мне. Я бы рекомендовал этот подход поверх обработчика событий, потому что вам нужно будет использовать ItemUpdated, что означает, что вам придется выполнять хитрые проверки, чтобы убедиться, что это выполняется только один раз. И другой вариант, который я могу придумать, это создание нестандартной формы, не очень удобно делать все время.
Теперь создайте свой собственный рабочий процесс. Обязательно инициализируйте свойства workflowProperties, как показано в ссылке для onWorkflowActivation_Invoked. Это очень простой рабочий процесс, если вы заполните все обязательные поля в форме. В представлении конструктора все, что вам нужно, - это 2 дополнительных действия, кроме действия OnWorkflowActivation: действие OnWorkflowItemChanged и действие кода. Для действия OnWorkflowItemChanged единственное свойство, которое необходимо установить, - это CorrelationToken, который будет таким же, как CorrelationToken действия OnWorkflowActivation. Теперь дважды щелкните действие Code, чтобы сгенерировать его метод codeActivity_Executed. В этом методе должно быть достаточно следующего:
SPListItem item = workflowProperties.Item;
if (!item.File.Url.Contains("/NativeUrl/"))
{
string destination = item.ParentList.RootFolder.Name + "/NativeFile/" + item.File.Name;
item.File.CopyTo(destination, true);
}
Я добавил оператор if, потому что рабочий процесс, вероятно, будет запускаться для нового элемента, созданного с помощью CopyTo, поэтому он проверит, находится ли файл в папке, и если он есть, он не будет выполнять копия. Теперь свяжите рабочий процесс с вашим сайтом, как показано в ссылке, и свяжите его с созданием элемента. Тогда должно сработать.
Несмотря на то, что этот рабочий процесс технически ожидает ItemUpdated, поскольку именно тогда поля заполняются, связывая его с созданием элемента, вы гарантируете, что он запускается только один раз. Я признаю, что использовал только item.File.MoveTo(destination, true)
, но при этом сохраняются все поля и метаданные, так что я уверен, что CopyTo также должен. Если нет, просто закричите.