I have WCF service consumed by AJAX client using SOAP 1.2
Web.config:
<endpoint address="" binding="wsHttpBinding"
contract="WcfService1.IService1" bindingConfiguration="wsHttpBin">
<wsHttpBinding>
<binding name="wsHttpBin">
<security mode="None"/>
</binding>
</wsHttpBinding>
From what I have read, I have to use <security mode="None"/> since a service exposed with “wsHttpBinding” binding implements WS-Security of WS-* family of web service specifications. As the binding uses security, the request will be rejected since AJAX doesn't support the security context.
My WCF service behavior is defined with InstanceContextMode.PerSession:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerSession)]
but when I consume it, the service behave as PerCall and every call starts a new WCF instance instead of using the current instance.
Why InstanceContextMode.PerSession behave like PerCall when using wsHttpBinding?
What can I do?
Sessions, when used over HTTP, are only supported by WCF when using security sessions or reliable sessions. If you can't use either then you have to implement a session mechanism by yourself. If you control both the client and the server side, it would be quite easy to do it. Here's how:
Create a class that holds all the session data you need stored (let's call it
SessionData), plus an additionalDateTimefor when the session was last used. Then add to your service class (or any other class) astaticConcurrentDictionary<string, SessionData>.When a client makes a call to your service, require it to pass a unique string that identifies the session (it can be randomly generated on the client side). Whenever a client calls you service, look up the session string in the dictionary and retrieve the session data (and update its content as needed). If it doesn't exist, create a new entry in the dictionary. Also, every time you access the
SessionDataobject, update the 'last used'DateTimeto the current time. A background task should periodically clear out old sessions that haven't been used in a while.That's it - you've implemented sessions on your own. You can now use
InstanceContextMode.Singleand not worry about WCF correctly creating instances of your service class per session.EDIT: If you're writing your WCF service with .NET 4.5 and you web application only targets modern browsers, you can use
NetHttpBindingon the server side and WebSocket on the client side.NetHttpBindingsupports session (when specifyingSessionMode.Required).