I am using message inspector in WCF application to store request & responses, into DB.
Whether to store these data in DB or not has to be restricted based on userInput received in the front-end.
To cut the long story short, I need help to address these issues -
States in page context are not available in the extensibility points
interface.
Inspectors method also do not accept any custom
parameters.
In this case, How can we pass the parameters to the WCF extensibility points for customizations?
Well the IDispatchMessageInspector interface receives a IClientChannel on each call, which is in turn an IExtensible. You would have to implement an custom IExtension, and extend the client channel when it's initialized (using an IChannelInitializer implementation). You could then retrieve the extension from the channel parameter in the inspector method implementation, and use it as a means of communication with you front end..
Related
I have a class that is exposed as a WCF service. The class lifetime is managed by Castle Windsor, which attaches a number of interceptors like logging aspect and permission aspect. With WCF I can pass some additional data in message headers, like the username or a userSessionId. Then on the server side the Permission interceptor can use OperationContext.Current.IncomingMessageHeaders and read which user is making the call. Then it can allow the invocation to proceed or throw an exception.
The problem is that now I want to ditch WCF and replace it with something else (RabbitMQ to be excact). How can I get a similar functionality to WCF OperationContext.Current, but without WCF? Or otherwise add some additional data to an IInvocation, so the interceptor would be able to read? The interceptor must be transparent to the rest of the world as usual.
I am new to WCF services and currently testing out things.
I have got a little REST API, which has several methods. Some of them require a user context (session), some others don't. At login, each user gets a session token. The client should supply this token and his user ID on every request via HTTP headers.
At the moment, I wrote a method for getting those two headers and validate the session, calling it on every method which will need a user context. This seems kinda nasty if the API gets bigger.
Is there a better approach for doing this?
You can leverage of following solutions:
Custom class deriving IClientMessageInspector/IDispatchMessageInspector for client and service respectively. Then you add its instance to MessageInspectors. Advantage of having messageInspector is that it's applied to single endpoint so regardless of having many endpoints exposed (both SOAP and REST), messageInspector can be associated only with single one. Whenever message is either received or sent, AfterReceive or BeforeSent method is invoked respectively. There you retrieve headers and if token does not match any expected you can throw an exception. Such a way out provides separation between exposed contract and background checks such as token validation.
Custom class deriving IOperationInvoker. Within custom operation invoker you explicitly call method and thanks to it you can examine headers (OperationContext.Current.IncomingMessage) before any method gets invoced.
I brought up only concepts, extensive information and examples can be looked up on Internet.
Based on the processing of the incoming request I have to store the original (unserialized) message as string to a database.
So far I implemented a DispatchMessageInspector and a ServiceBehavior that I used to decorate my service implementation. My DispatchMessageInspector has a property to which I store the message string. My service implementation includes some business rules that check the request and if this check fails I'd like to store the original message.
How can I achieve to access the message string property of my DispatchMessageInspector from the service implementation in an elegant way?
You can add a Message Property containing the raw message in a form you like. Then in your service, you can access them through OperationContext.Current.IncomingMessageProperties["RawMessage"].
I have a WCF REST-service that is used by a mobile application used in different countries. It's accepting and returning JSON, and I use StructureMap.
The idea is to create one service instance for all countries, but I need to know what country is calling the service and do some logic on that in the service (for example, determine the connection string to be used).
however, I want to avoid that country code has to be passed with each service request. What are my options here?
Can I, for example, have one endpoint for each country? But in that case, how can I know what endpoint/country code was used to call the service?
Maybe other possibilities?
Multiple endpoints could be a solution, but you need a reliant way of determining which endpoint was actually used. Given the "disconnected" nature of WCF REST services (by that I mean the usage of non WCF types to do the communication and just using the WCF attributes), this would require you to write a WebHostFactory that specifies the country on creation of the service for a given endpoint. What you could to is inspect the WebOperationCurrent.Current instance to get access to information hidden from your method signature. For example:
Uri requestRoot = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri;
if (requestRoot.PathAndQuery.Contains("en-us")) {
// use english locale
}
else if (requestRoot.PathAndQuery.Contains("de-de")) {
// use german locale
}
You would need a better strategy to determine the actual country/language, but the basic idea is to re-host the same service under multiple paths and inspect those paths within the request using the current WebOperationContext instance.
Edit
From the comments above, I would like to add that you have access to the UserAgent string for the current request using the WebOperationContext. So you could also inspect those information looking for a clue about the requested language. But keep in mind that those "implicit" information are only clues but never clear indications about what the user wants.
I am reading about MessageContract & MessageHeader and trying to understand the use case of sending some info in MessageHeader and not use it just as a function parameters?
Message contracts and message headers are somewhat advanced concepts which most people will never need to use. They're mostly used in interoperability scenarios where you need to communicate with a 3rd party service which expects the data in a certain format (i.e., some parameters in the headers).
Other possible scenarios for passing some parameters in message headers:
Headers can be easily accessed in message inspectors and other extensibility points in WCF (since headers are always buffered), so if you want to use some of those to do some validation (for example, some authentication decision), you may want to have the parameter in the header
As #Vasile mentioned, if you want to have a streamed transfer, since the headers are always buffered they can be used to convey some additional information to the operation prior to the (streamed) body being read / consumed
The MessageContract & MessageHeader provides lower-level control of your messages than DataContract & DataMember. Also it provides a way to create SOAP Headers if you're using webHttpBinding or basicHttpBinding.
If you're using streaming capabilities in your WCF service, than using MessageHeader is the only way to pass data besides the stream itself.
You can read more about message contracts in this MSDN article