Reputation: 8276
I have an IClientMessageInspector
interface with BeforeSendRequest()
method implemented.
In this method I want to retrieve the Session
object set in the client. Something like.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
//Instantiate new HeaderObject with values from ClientContext;
var dataToSend = new MyCustomHeader
{
MyValue = HowDoIGetClientSession["abcValue"];
};
var typedHeader = new MessageHeader<CustomHeader>(dataToSend);
var untypedHeader = typedHeader.GetUntypedHeader("custom-header", "s");
request.Headers.Add(untypedHeader);
return null;
}
I think I need something very similar as in this question.
Upvotes: 2
Views: 469
Reputation: 8276
I ended up using an approach like in this tutorial.
I add the relevant information in a cookie as key-value pairs and read it in the service implementation. Instead of service reference I am using ChannelFactory
, but basically the main idea is the same as in the tutorial.
My BeforeSendRequest
method is:
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name
, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers["Cookie"]))
{
httpRequestMessage.Headers["Cookie"] = cookie;
}
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add("Cookie", cookie);
request.Properties.Add(HttpRequestMessageProperty.Name
, httpRequestMessage);
}
return null;
}
The binding settings is:
<basicHttpBinding>
<binding name="basicHttp" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="20000000" maxBufferSize="20000000" maxReceivedMessageSize="20000000"
textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"
messageEncoding="Text">
<readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
In the client app I needed (in web.config
system.serviceModel
):
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
And in the service implementation class annotation:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
public class MyService : IMyService {
// ...
}
For service calls I am using a wrapper object which implements IDisposable
, takes case of proper disposal and adding to EndpointBehaior
to the ChannelFactory
before creating the channel.
_factory = new ChannelFactory<T>( );
_factory.Endpoint.Behaviors.Add(new CookieEndpointBehavior(cookieStr));
_channel = _factory.CreateChannel();
I am using the service wrapper class in using block
, which will call Dispose
, once it reaches out of scope.
Upvotes: 0
Reputation: 3757
If both your client application and WCF service are hosted in same application (actually virtual application in IIS), you can share your session state.
But you need to enable ASP.Net compability mode within your WCF (see this: https://msdn.microsoft.com/en-us/library/ms752234.aspx)
If your applications are hosted in different applications, you can still do it, but you must use an external storage for you session, like a Session State server (see more here: https://msdn.microsoft.com/en-us/library/ms178586%28v=vs.140%29.aspx).
You proceed the same way, but you must set in both web.config files the same session storage.
Hope it helps.
Upvotes: 0