WCF - Generalizing Action String
I have to take some pre-defined WSDL's (I do not control these), and expose them on our device to reply to various SOAP/UPnP requests.
Anyway, I have all of this working, but the problem comes through because I have one service that could be requested on any number of channels. I'll explain:
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:some:namespace:1", ConfigurationName="myInterface")]
public interface myInterface
{
[System.ServiceModel.OperationContractAttribute(Action="urn:some:namespace:1#GetConfiguration", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
[return: System.ServiceModel.MessageParameterAttribute(Name="config")]
MyConfigurationResponse GetConfiguration(MyConfigurationRequest request);
}
Basically, what I'm attempting to do (I realize this syntax is completely wrong but I think it will get the point across) is this:
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:some:namespace:{channelNumber}", ConfigurationName="myInterface")]
public interface myInterface
{
[System.ServiceModel.OperationContractAttribute(Action="urn:some:namespace:{channelNumber}#GetConfiguration", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
[return: System.ServiceModel.MessageParameterAttribute(Name="config")]
MyConfigurationResponse GetConfiguration(MyConfigurationRequest request, String channelNumber);
}
I simply would like some portion of my original Action message passed in as a parameter to the method I'm implementing.
The only other way I have thought of that I could implement this, would be to specify some other method, we'll call it Dispatcher with the Action="*", and then manually parse the received action using OperationContext.Current.IncomingMessageHeaders.Action
. This just seems like a really shady way of doing things. I'm certain that the main roadblock here is my inexperience with WCF.
Any help you're able to provide would be m开发者_开发技巧uch appreciated.
Thanks,
The easiest way to manage this is to create a generic message handler. The contract would look something like this:
[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface ICatchAll
{
[OperationContract(IsOneWay = false, Action = "*", ReplyAction = "*")]
Message ProcessMessage(Message message);
}
The idea is that you create a "router" method for your service along the lines of this article. You'll still need to create the individual channel service contracts to shape the soap message to be received & returned but you'll have the client endpoint go to your "router" service endpoint. You may be able to do something along these lines with the new WCF 4 RoutingService if you create a separate instance of each channel service contract.
The only generalization of action method is the wild card * and it is usually used with both input and output as generic Message
.
There is a way to customize whole behavior of the operation selection and parameters definition and filling. You can check following interfaces:
IDispatchOperationSelector
is used to select operation based on incomming dataIOperationInvoker
is used to allocate parameters and invoke the operation selected byIDispatchOperationSelector
IDispatchMessageFormatter
is used to fill parameters for the operation to allocation slots prepared byIOperationInvoker
You probably don't need to implement them all but they will allow you to customize the behavior in any way you need. For example of custom selector and formatter check MSDN samples for example of custom invoker check this article. Anyway this whole infrastructure coding will just move your Action parsing to some WCF internals but you will still have to do that to get it as operation parameter.
精彩评论