.NET WCF store session data without persistence or clean implementation
I've written a WCF service that exposes a large number of methods, each one of them is basically a database query. There are however multiple databases, so now each 开发者_开发百科method has a first argument being the name of the database.
At the client side, one session only uses one database, so I don't want to pass the name of the database each time a call the service. Ideally I want to send the database name to the service first, which stores it in memory for all future queries. The problem is that my client is written in classic ASP and therefore I'm using basicHttpBinding, so there is no persistence across calls on the server.
My question now is, is there another way and if not how would I implement this nicely so I don't have the database name in each method signature.
I can of course use something like the Command pattern and create for each call an object containing the neccessary data (including the database name using inheritance), but that would result in a lot of classes (on the server and on the client). Another option is to use a dictionary, but then my server method doesn't specify its arguments which makes it harder to maintain. I've thought about using reflection, but that seems a bit overkill to me...
Any suggestions?
I don't know of any WCF-specific solution for this. But you can always solve this problem by creating a method that stores the client identification and the desired database in the first requests, so subsequent requests can query that store.
You can try to use this sample to build cookie based session - the same is supported in ASMX. Your service will be able to access ASP.NET session but it requires AspNetCompatibility. You can also try to combine it with custom IInstanceProvider and build custom session management controlled by cookie.
You can rely on this answer, it is about enabling ASP.NET like session.
If the desired client runs ASP I would probably go for the suggested AspNetSession solution. However if you cannot rely on AspNetSessions then you can rely on using the HTTP-Headers for sending that information on each call. On the first call, when the database is defined, the server takes the information about what database to take directly from the method parameter and stores it into an HTTP Header.
OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHeader(HEADER_NAME, NAMESPACE, yourDbName));
There must be a way in classic ASP to retreive that information, but I am no expert on this.
http://www.w3schools.com/asp/coll_servervariables.asp
indicates that you can just access it though. On all subsequent calls, the client sends that header information to the server again.
on the server you read it by doing
int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(HEADER_NAME, NAMESPACE)
string yourDbName = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(headerIndex);
This way your Server code does not get polluted and you can automate the putting and getting of that information from the header into an own class so your Service implementation is not aware where that information is coming from.
精彩评论