Попытка заставить повышение статуса участника с сохраняемостью работать со службой xamlx в WF4

#workflow #workflow-foundation-4

#рабочий процесс #рабочий процесс-foundation-4

Вопрос:

Я внедрил продвижение участника с сохраняемостью рабочего процесса, точно так же, как это показано здесь, на веб-сайте Microsoft: http://msdn.microsoft.com/en-us/library/ee364726(VS.100).aspx и пока кажется, что все работает. Я не вижу сохранения данных в базе данных при запросе? Я думаю, что я пропустил какой-то шаг или Microsoft что-то пропустила.

Я использую workflow application .xamlx service и переопределил WorkflowServiceHost. Кажется, все работает нормально, поэтому я не уверен, в чем может быть проблема?

Итак, мой вопрос здесь в том, есть ли у кого-нибудь реальный рабочий пример того, как реализовать участника сохранения?

Я попробовал несколько разных подходов к этому

Но, похоже, я просто не могу заставить это работать.

К вашему сведению — этот код работает, когда я изменил пространства имен, чтобы они соответствовали. Благодаря Морису

Код WorkflowServiceHost:

 public class ServiceHostFactory :WorkflowServiceHostFactory
{
    private static readonly string m_connectionString =
            "Data Source=localhost;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses)
    {

        return base.CreateWorkflowServiceHost(activity, baseAddresses);

    }

    protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)
    {

        WorkflowServiceHost host = base.CreateWorkflowServiceHost(service, baseAddresses);
        host.DurableInstancingOptions.InstanceStore = SetupInstanceStore();

        SqlWorkflowInstanceStoreBehavior sqlWorkflowInstanceStoreBehavior = new SqlWorkflowInstanceStoreBehavior(m_connectionString);
        XNamespace xNS = XNamespace.Get("http://contoso.com/DocumentStatus");
        List<XName> variantProperties = new List<XName>() 
        { 
           xNS.GetName("UserName"), 
           xNS.GetName("ApprovalStatus"), 
           xNS.GetName("DocumentId"), 
           xNS.GetName("LastModifiedTime") 
        };
        sqlWorkflowInstanceStoreBehavior.Promote("DocumentStatus", variantProperties, null);
        host.Description.Behaviors.Add(sqlWorkflowInstanceStoreBehavior);

        //Add persistence extension here:
        host.WorkflowExtensions.Add<DocumentStatusExtension>(()=>new DocumentStatusExtension());;
        host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });            

        // Handle the UnknownMessageReceived event.
        host.UnknownMessageReceived  = delegate(object sender, UnknownMessageReceivedEventArgs e)
        {
            Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Unknow Message Recieved:{0}", e.Message));
        };


        return host;
    }

    private static SqlWorkflowInstanceStore SetupInstanceStore()
    {


        SqlWorkflowInstanceStore sqlWorkflowInstanceStore = new SqlWorkflowInstanceStore(m_connectionString)
        {
            InstanceCompletionAction = InstanceCompletionAction.DeleteAll,
            InstanceLockedExceptionAction = InstanceLockedExceptionAction.BasicRetry,
            HostLockRenewalPeriod = System.TimeSpan.Parse("00:00:05")
        };
        InstanceHandle handle = sqlWorkflowInstanceStore.CreateInstanceHandle();



        //InstanceHandle handle = sqlWorkflowInstanceStore.CreateInstanceHandle();
        //InstanceView view = sqlWorkflowInstanceStore.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
        //handle.Free();
        //sqlWorkflowInstanceStore.DefaultInstanceOwner = view.InstanceOwner;

        return sqlWorkflowInstanceStore;
    }
  

DocumentStatusExtension Code:

         public string DocumentId;
    public string ApprovalStatus;
    public string UserName;
    public DateTime LastUpdateTime;

    private XNamespace xNS = XNamespace.Get("http://contoso.com/");

    protected override void CollectValues(out IDictionary<XName, object> readWriteValues, out IDictionary<XName, object> writeOnlyValues)
    {
        readWriteValues = new Dictionary<XName, object>();
        readWriteValues.Add(xNS.GetName("UserName"), this.UserName);
        readWriteValues.Add(xNS.GetName("ApprovalStatus"), this.ApprovalStatus);
        readWriteValues.Add(xNS.GetName("DocumentId"), this.DocumentId);
        readWriteValues.Add(xNS.GetName("LastModifiedTime"), this.LastUpdateTime);

        writeOnlyValues = null;
    }

    protected override IDictionary<XName, object> MapValues(IDictionary<XName, object> readWriteValues, IDictionary<XName, object> writeOnlyValues)
    {
        return base.MapValues(readWriteValues, writeOnlyValues);
    }
  

Код обновления расширения:

 public sealed class UpdateExtension : CodeActivity
{
    // Define an activity input argument of type string
    public InArgument<string> Text { get; set; }

    // If your activity returns a value, derive from CodeActivity<TResult>
    // and return the value from the Execute method.
    protected override void Execute(CodeActivityContext context)
    {
        // Obtain the runtime value of the Text input argument
        context.GetExtension<DocumentStatusExtension>().DocumentId = Guid.NewGuid().ToString();
        context.GetExtension<DocumentStatusExtension>().UserName = "John Smith";
        context.GetExtension<DocumentStatusExtension>().ApprovalStatus = "Approved";
        context.GetExtension<DocumentStatusExtension>().LastUpdateTime = DateTime.Now;
    }
}
  

Ответ №1:

Они у меня работают, к сожалению, пока нет примера кода, которым я могу поделиться. Может быть немного сложно настроить PersistenceParticipant со всеми задействованными XNames, которые должны совпадать. Кроме того, существует ошибка с использованием логических значений, которая останавливает весь процесс без предупреждения, поэтому убедитесь, что вы избегаете логических значений.

Обновление: в вашем коде используются разные пространства имен XML. CreateWorkflowServiceHost() использует http://contoso.com/DocumentStatus для определения свойства promotion и CollectValues() использует http://contoso.com / как пространство имен XML для собранных значений. Оба должны быть одинаковыми.

Комментарии:

1. Спасибо Морису за совет по логическим значениям, а также за ваши видео. :).

2. Можете ли вы взглянуть на мой код хоста и посмотреть, видите ли вы, что я чего-то не хватает? заранее спасибо — я только что добавил sqlWorkflowInstanceStoreBehavior, который был показан здесь, и это не сработало. msdn.microsoft.com/en-us/library /…

3. Спасибо, Морис! Ваше замечание об ошибке Boolean положило конец отладке, стоившей целый день в нашей компании! После того, как мы узнали, что искать, мы нашли это: support.microsoft.com/kb/2022538

4. @TrueWill у вас, случайно, нет того, что вы сделали для этой логической ошибки? Кстати, ссылка не работает

5. @Jivan Я этого не делаю — это было более пяти лет назад в другой компании. Похоже, что ссылка пропала (даже на Wayback Machine). Я обнаружил, что это связано с этим: «Однако продвижение поддерживается только для некоторых простых типов. При попытке продвижения свойства неподдерживаемого типа, такого как Boolean, эпизод сохранения завершается неудачей, а затем экземпляр прерывается.»