Yesterday I posted a question on the Windows Communication Foundation forums about how to get the SOAP Action associated with a given operation when all I had was the OperationDescription for it. I had been looking for a while and had not been able to make the connection. Here's what I asked:
Is there an easy way to get an operation's SOAP Action when all you have is the OperationDescription representing the method?
Here's the scenario I'm looking at: I have a custom service behavior that injects a custom IDispatchMessageInspector into several of the endpoints of the service. That part works just fine.
However, when I get to the AfterReceiveRequest() method, all I have in hand is the request message, from which all I know is the SOAP Action it contains, and what I really need is the name of the operation it maps to. I can get the System.ServiceModel.Description.ServiceDescription object directly in my service behavior and pass that to my message interceptor, and from there on I could easily get at the OperationDescription objects for all endpoints/contracts associated with the service.
So, on one hand I have easy access to the action, and on the other easy access to the operation name, and I'd like to connect them together. Since the OperationDescription doesn't include the action, I know I could get it by manually looking for the [OperationContract] attribute on the BeginMethod, but that would be rather bothersome and I guess imply replicating the code in the internal NamingHelper.GetMessageAction(), which I'd rather not do.
Any other ideas?
Brian McNamara was s kind enough to answer my question with a few options and things to watch out for:
You can get the Action/ReplyAction out of an OperationDescription by using
od.Messages[0].Action
od.Messages[1].Action
assuming that 'od' is the OperationDescription.
Note that if the operation is one-way, only Messages[0] will be populated (Messages[1] will cause an out-of-bound exception).
(Beware that this approach of correlating messages to operations only works if you are using the default IDispatchOperationSelector (which dispatches based on action). If someone plus in their own custom IDispatchOperationSelector, then the logic of using the action to determine the operation may be incorrect.)
(Note also that if you have a duplex contract (a ServiceContract with a CallbackContract), there may be up to two operations with the same action - one in each direction. od.Messages[0].Direction will tell you if this operation is a normal operation (MessageDirection.Input) or a callback operation (MessageDirection.Output).)
Many thanks to Brian for his help! If you're wondering why I'm reposting it here, well that's easy: it will make it easier for me to find it whenever I need it again :-)
Technorati: Windows Communication Foundation, WCF, WCF Extensibility