简体   繁体   中英

Can't redirect to another page using ASP.NET and WF 4

I am using WF 4 with ASP.NET and as part of the workflow the system may need to redirect to other pages for the user to input additional information under certain circumstances. Once they have entered that information, the system needs to resume the workflow where it left off.

I have this code so far in the initial page that kicks off the process and an activity in the workflow that sets a bookmark.

static InstanceStore instanceStore;
static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);
static Guid id;

protected void Page_Load(object sender, EventArgs e)
{
    SetupInstanceStore();
}
protected void btnStartWorkflow_Click(object sender, EventArgs e)
{
    app = Session["applicant"];

    Dictionary<string, object> workflowInputs = new Dictionary<string, object>();

    workflowInputs.Add("Applicant", app.Applicant);
    WorkflowApplication workflowApplication = new WorkflowApplication(new IdentityCheckActivites.IdentityCheckWorkflow(), workflowInputs);

    workflowApplication.InstanceStore = instanceStore;


    //returning IdleAction.Unload instructs the WorkflowApplication to persist application state and remove it from memory  
    workflowApplication.PersistableIdle = (a) =>
    {
        return PersistableIdleAction.Persist;
    };

    workflowApplication.Unloaded = (a) =>
    {
        instanceUnloaded.Set();
    };

    workflowApplication.Completed = (a) =>
    {
        instanceUnloaded.Set();
    };


    workflowApplication.Persist();
    id = workflowApplication.Id;
    workflowApplication.Run();

    Session["id"] = id;

    workflowApplication.Idle = (a) =>
    {
        instanceUnloaded.Set();
    };

    instanceUnloaded.WaitOne();

    var bookmarks = workflowApplication.GetBookmarks();

    if (bookmarks != null && bookmarks[0].OwnerDisplayName == "CC")
    {
       workflowApplication.Unload();
       Context.Response.Redirect("SecondPage.aspx");
    }            

    Context.Response.Redirect("FinalPage.aspx");

}

private static void SetupInstanceStore()
{
    instanceStore = new SqlWorkflowInstanceStore(@"Data Source=xxx;Initial Catalog=SampleInstanceStore;User Id=xxx;Password=xxx;Asynchronous Processing=True");

    InstanceHandle handle = instanceStore.CreateInstanceHandle();
    InstanceView view = instanceStore.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
    handle.Free();

    instanceStore.DefaultInstanceOwner = view.InstanceOwner;
}

This seems to work very well in that it persists the workflow to the database and if the bookmark is set I want to redirect to a second page for the user to enter more data.

This is the part of the code that I am having problems with: -

var bookmarks = workflowApplication.GetBookmarks();

if (bookmarks != null && bookmarks[0].OwnerDisplayName == "CC")
{
   workflowApplication.Unload();
   Context.Response.Redirect("SecondPage.aspx");
}            

Context.Response.Redirect("FinalPage.aspx");

If there's a bookmark set, I redirect to an intermediary page, if not and no user intervention was necessary, the page will just redirect to the final page.

This works if the bookmark is set, but if not the workflowApplication.GetBookmarks() statement throws an exception telling me that the workflow has completed.

I can't seem to find a way to detect at this stage which state the workflow is in so that I can redirect to the relevant page.

Maybe I have the wrong idea in general, as much as I search though, I cannot seem to find a lot of guidance on this subject.

Any ideas?

Thanks,

Jim.

instead of

               workflow.idle 

you need

           wfApp.PersistableIdle 

and don't forget

            instanceUnloaded.Set();

I don't think there is a way to directly determine if the workflow is completed from WorkflowApplication (except for catching and inspecting the exception that is thrown).

But you could set a flag in side your Completed delegate which is executed only if the there is no bookmark set and the workflow is completed. You could then check this flag before calling GetBookmarks().

Not sure if I understand exactly, but it seems that your page controller is looking at the state of the workflow to understand what page to redirect to? The problem is that the state may be non-existent if the WF instance has ended?

If the above is correct then perhaps the approach is wrong. A more appropriate approach might be to have a WCF WF service on AppFabric (correlated by session id) handle the website request directly. (If a user in a particular session visits the site, then the WF determines what page to render, and if the user hits a certain button, then send a WCF WF message using net pipe binding)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM