When using ContextManager in WorflowService scenario, it can happen that the instance of the manager does not exist at all.
To illustrate this, take a look on following sample:
MyDemoSvcClient demoSvc = new Consumer.WfSvcDemo.MyDemoSvcClient(); demoSvc.PushA(1); IContextManager ctxMg = demoSvc.InnerChannel.GetProperty<IContextManager>();
Sometimes, it can happen that the variable "ctxMg" is empty. This is the case when instead of *HttpContextBinding the common *Binding is used. For example the client uses basicHttpBinding. Usually, after importing of service reference on the client's side, a common WCF binding is used and not expected workflow context binding. That means, if service is configured to use wsHttpContextBinding the client will import wsHttpBinding.
This seems to be strange, but it is a good choice. By avoiding of the context binding, the client is not required to use WorkflowService functionality implemented in System.WorkflowServices.dll. This specially makes a sense in an interop-scenario, where any client could invoke operations on workflow service. However, if the client needs features like context-persistance etc. you ill have to find a way how to do it, without of WCF.
Recap: If you need to deal with workflow context, use one of WCF-context-bindings, which are implemented in System.WorkflowServices assembly. Otherwise you will have to provide context-header value by
yourself.
When all works fine you can do something like this to invoke the second operation on already running workflow, after recycling of the client:
ctxMg.SetContext(ctx);
demoSvc.PushB(2); If the client has been recycled (restarted) after the first operation has been invoked and the second operation on already running workflow is invoked (see sample above), without of setting of the context value following error will occur:
"There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized."
Here is the whole example with "restarting":
MyDemoSvcClient demoSvc = new MyDemoSvcClient();
demoSvc.PushA(1);
IContextManager ctxMg = demoSvc.InnerChannel.GetProperty<IContextManager>();
IDictionary<string, string> ctx = ctxMg.GetContext(); // Simulates restart of the client.
demoSvc = new MyDemoSvcClient();
ctxMg.SetContext(ctx);
demoSvc.PushB(2);
Posted
Apr 22 2008, 02:41 PM
by
Damir Dobric