Controller.UserData question

Topics: Web Client Software Factory, Project Management Forum, UIP Application Block discussion, User Forum
Jun 27, 2007 at 1:10 AM
Lets say I save a GUID to my UserData collection when I run the Suspend method. I am going to later pass this GUID back into my web application via a URL.

Is there anyway possible I can retrieve the state information based on that GUID. It doesn't like I can retrieve UserData based on a certain GUID.

Any ideas? With UIP you could do this but I am think I am missing it here.

Jun 27, 2007 at 3:26 PM
I think it is unsopported. Following some alternatives you might use.

One way you can implement it is by providing your own implementation of IPageFlowCorrelationTokenProvider. You can take a look at the source CookiePageFlowCorrelationTokenProvider that comes with the factory and create your based on it. What you need is a different implementation in the GetCorrelationToken method. In there, you can get the GUID from the query string of the request. You might or might not want to leave the cookie implementation, in case the Request's query string doesn't contains a GUID. Doing it this way, ensures that as long as the guid is on the query string requests, those would be treated as part of the same page flow instance.

An alternate scenario might be needing to apply it only to certain page flows. In this case you provide your own implementation of IPageFlowInstanceStore. You can base your implementation on PageFlowInstanceCorrelationSqlProvider, detect the type of page flows that you want to handle specially (i.e pageFlowInstance.Definition.PageFlowType) perhaps using attributes on the page flow class or by having some configuration entries, and grabbing/mapping the correlation token from the url in the corresponding methods.
Jun 27, 2007 at 5:49 PM
Thanks Freddy.

One way i figured out to do this and I am not sure if it is going against practice, however, I made it work in the PageFlowWithShoppingCart quickstart.

This is by dynamically naming your UserData key with the GUID. However, when you CompleteCheckout for a user it deletes all the UserData keys.

My users will all be different. So I dont think this would be a problem? Thoughts?


Jun 27, 2007 at 7:59 PM
I can think of the following 2 issues that you might face using that approach:

- It will only work if both requests are originated in the same client computer. This means that it won't work if you are planning using some kind of feature where you send a mail the url to the user or perhaps another user, and the user can continue the process later from a different computer.
- The site requires cookies. This is a general concern and applies to the whole use of the pageflowprovider. It is caused because of the use of the default correlation provider: CookiePageFlowCorrelationTokenProvider.

If you don't need to address those, your solution seems pretty effective.

Great job. Let us know any additional findings.
Jun 27, 2007 at 9:03 PM
Darn! I was planning on using an email that will be sent to the user with a URL. Which you mentioned will not work.

It is starting to look like I will have to use the UIP block for my work. Trying to avoid that and using some some newer technologies.

Might have to try my own implementation but really do not have enough time. Thanks for your help so far!


Jun 28, 2007 at 9:52 AM
Replace the CookiePageFlowCorrelationTokenProvider with your own provider and you have a chance on doing your solution.

Jun 28, 2007 at 4:55 PM
I don't really need to authenticate here. Would it matter if I "hard coded" the CookiePageFlowCorrelationTokenProvider to return the same thing?

My UserData store is going to hold the unique values.


Jun 28, 2007 at 6:53 PM
It appears to be working beautifully!! Any long term effects from this that you can think of???

The GUID in the querystring is what will be the unique identifier for retrieving a persons page state.
Jun 28, 2007 at 10:29 PM
One thing you cannot do is run the IPageFlow.Complete() method. As it will wipe out all of the data for each of my different users.
Jun 29, 2007 at 7:48 PM
Hi Jordan,

As it already seems you know, you are sharing your workflow instance between all your users, meaning you probably will only be able to use it as a state storage.

Seeing the type of overal behavior overriding you are willing to use on the correlation provider, I suggest your implementation just returns the ID on the query string as the correlation token i.e return Request.QueryString"GUID". Then you only need to be sure that all the pages in the workflow are accesed using a guid created before calling the first page.

Thus, before calling the first page you create a new guid and pass it on the query string parameter. If you stick to calling Next or Navigate (if required) on the workflow to handle all the navigation in the page flow, then you can also override the INavigateService to set the GUID on the query string for you (it only has a RedirectTo method). The issue here is that the NavigateService isn't a provider (thus its replacement configuration enabled) ... it is set on the constructor of the following class: "WorkflowFoundationPageFlowFactory".

- You are able to use the page flow in its designed way, meaning you get to be able to use the flow part of it and it related benefits.
- You only have to set the GUID manually on the first request (or of course in the mail you will be sending).
- You get what you need.

- The correlation provider depends on external factors (GUID being set externally while still being unique).
- A guideline would need to be followed on how to init a flow.
- Either the "WorkflowFoundationPageFlowFactory" class or the "NavigateService" class will be modified, not using an extensibility hook provided by the factory. This hides the implementation (making it harder for someone else to understand) and also more prone to being affected by upgrades to the page flow block.
- I don't know if the factory allows you to configure a provider for one set of pages, and another one for others.
Jun 29, 2007 at 8:35 PM

all i really care about is state storage. Mainly suspend and resume using a "key" like in the UIP. However I didnt want to have to use the UIP block if I could leverage some new technologies.

The applicaiton is fairly small so the Workflow is not a big concern. Most likely the user will all be going to the same spot. I will look into the other ideas you have. I hope not to run into any problems down the road but so far I think I can work with it in this way going forward.