We are using CSLA 4 with a WCF Dataportal and using the ApplicationContext.ClientContext to send user specific data to the server.
When doing concurrent testing we spotted that the ApplicationContext on the server was not scoped to the individual request - it turned out that the context was being stored in the Thread object and multiple requests (from different users) were often on the same thread. After reading page 206 of the VB 2008 BOs book it was clear we needed to get the server to use HttpContext instead.
We have now done this, but I want to check that our approach is correct. We have:
- added the aspNetCompatibilityEnabled="true" setting to the serviceHostingEnvironment node in the web.config. This gives the WCF Service access to the current HttpContext.
- added a reference to the Csla.Web project in our CSLA business library. This is required so that the ContextManager can use the Csla.Web.ApplicationContextManager class (which uses HttpContext to store the ApplicationContext).
Is this the correct approach? I can't help wondering whether we took a wrong turn somewhere else and there is another way to achieve this. I am also wondering why you would ever want a CSLA WCF Dataportal to not use the HttpContext - even if you aren't using the ClientContext/GlobalContext objects you are likely to be using the User object for server-side authorization, and you wouldn't want this put in the Thread object and shared across requests. Have we missed somthing?!
On any ASP.NET server, make absolutely sure that Csla.Web.dll is in the \bin directory.
ApplicationContext is managed differently depending on runtime context. ASP.NET is different from WPF, which is different from other .NET contexts.
The ASP.NET handler for ApplicationContext is in Csla.Web.dll, because Csla.dll can't reference System.Web.dll.
If Csla.Web.dll is in your \bin directory, CSLA will automatically switch to using the correct ASP.NET context handler.
Thanks Rocky. Can you just confirm the aspNetCompatibilityEnabled setting also required? If I remove this I lose the HttpContext, even with the System.Web.dll in place.
Compatibility mode should not be required, no.
ASP.NET doesn't guarantee that a request will run on the same thread throughout its life (though they usually do). And of course server threads are reused by subsequent requests from other users - it is just a thread pool after all.
So the only safe place to store per-request data is in HttpContext, which ASP.NET does guarantee will remain consistent through the life of a single request.
If Csla.Web.dll is in the bin directory, CSLA automatically switches to using a context handler from that assembly instead of the standard (thread-based) one in Csla.dll. That context handler simply stores the context on HttpContext instead of the thread, thus working correctly in ASP.NET.
Since HttpContext is consistent, regardless of any compatibility mode, your context values should work as expected on a per-request basis.
Thanks again Rocky. Sorry to keep on about this one, but I don't think the HttpContext is available to WCF Services hosted in ASP.NET unless you switch on ASP.NET Compatibility mode. I have found a few web posts about this. This one explains it well: http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx#_Toc125716003
If this is the case then I think this should be the default/recommended web.config setting for CSLA WCF Services? Otherwise the System.Web ContextManager finds the HttpContext.Current is null and falls back to the Thread store.
But... if I am barking up the wrong tree please tell me to stop this line of enquiry immediately!
Finally, possibly not the place for this, but thanks for all you hard work and dedication with CSLA - I have just completed a couple of projects using it and it has been an real joy to use.
I think you are correct. But the WCF team tells me that once user code has started running in a service (which means the CSLA data portal host class code) they won't switch out the thread.
In other words, WCF isn't subject to having threads swapped out while the service is executing. And that means that it should be safe to leave the context on the thread within a WCF service.
That's not true of ASP.NET in general as I mentioned, but within WCF there should be thread consistency.
To avoid cross-user "leaking", the data portal does clear the context values before the call returns to the client. This is important because the thread will be resused (as it is part of a thread pool).
Copyright (c) Marimer LLC