Ошибка при запуске custom workflow
Несколько дней потратил на мучение с одной очень неприятной ошибкой. Причем судя по результатам гугления можно сказать что очень многие сталкивались с этой ошибкой и мало кто представляет что с этим делать и из-за чего такое может происходить, по крайней мере я в интернете ответа так и не нашел, но до сути проблемы все-таки докопался - попытаюсь вкратце описать.
Итак.
Создаем workflow для SharePoint'а, например, пользуясь этой инструкцией, развертываем его на сервере, запускаем... Оп! Сбой при запуске, повторная попытка, бла-бла-бла. В логе SharePoint пишет что-то про пустой контекст и т.д. Хмм... смотрим в инструкцию, смотрим на свой код/дизайнер, ничего не понимаем, смотрим еще раз и т.д. как в том анекдоте про программиста и инструкцию на тюбике с шампунем.
Если смотреть многочисленные примеры создания workflow, то можно увидеть в них такую строчку в методе onWorkflowActivated_MethodInvoking:
workflowId = workflowProperties.WorkflowId;
Так-так-так. workflowId, думаем мы и добавляем в класс нашего workflow:
public Guid workflowId = default(System.Guid);
Без задней мысли. Правда ведь? Gotcha! В тех же примерах можно видеть, если прочитать их внимательней, что для Activity OnWorkflowActivated в свойствах в дизайнере нужно указать worflowId и workflowProperties (точнее создать их). Стоп. worflowId? Смотрим еще раз:
WorkflowProperties есть, но где же WorkflowId? Его нет. А указать его нужно. Вот так.
Баг? Фича? Может так все и задуманно?
Как заставить эту штуку работать? Открываем Workflow1.Designer.cs и под комментарием, в котором написано, что ничего руками исправлять ни в коем случае не нужно, в теле метода InitializeComponent дописываем следующи строки:
System.Workflow.ComponentModel.ActivityBind idactivitybind = new System.Workflow.ComponentModel.ActivityBind();
idactivitybind.Name = "Workflow1";
idactivitybind.Path = "workflowId";
this.onWorkflowActivated1.SetBinding(Microsoft.SharePoint.WorkflowActions.OnWorkflowActivated.WorkflowIdProperty, ((System.Workflow.ComponentModel.ActivityBind)(idactivitybind)));
После этого лучше сохранить и открыть дизайнер дабы проверить, что он нормально воспринял внесенные изменения. Теперь все должно работать!
З.Ы. Естественно, замените Workflow1 на название вашего workflow.
З.Ы. Судя по всему у многих все работает нормально. Это оттого, что они используют шаблоны проектов из последнего Starter Kit (например, здесь). В этих шаблонах при создании проекта есть один workflow, в нем уже есть OnWorkflowActivated activity, и уже установленны нужные свойства. Я не думаю, что этот шаблон хорош для больших проектов, где нужно создавать много рабочих процессов и других элементов features.
Мне очень понравилась утилита WSPBuilder. Я интегрировал ее в процесс сборки проекта по нажатию кнопки build и добавил код для обновления проекта на сервере. Рекомендую ;)