Reputation: 5822
This is my ABC on the server side:
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\imhmsgs"
binding="msmqIntegrationBinding"
bindingConfiguration="IncomingMessageHandlerBinding"
contract="TMC.Services.Contracts.Messages.IInboundMessageHandlerService">
As soon as I do an .Open()
to host the service, I get the exception:
Cannot serialize interface XYZ.Services.Contracts.Messages.Interfaces.IMyMessage.
My IMyMessage interface:
[ServiceContract]
[ServiceKnownType(typeof(IMyMessage))]
[ServiceKnownType(typeof(ConcreteMessage))]
public interface IInboundMessageHandlerService
{
[OperationContract(IsOneWay = true, Action = "*")]
void ProcessIncomingMessage(MsmqMessage<IMyMessage> incomingMessage);
}
The implementor for that interface:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
ReleaseServiceInstanceOnTransactionComplete = false)]
public class InboundMessageHandlerService : IInboundMessageHandlerService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void ProcessIncomingMessage(MsmqMessage<IMyMessage> incomingMessage)
{
}
}
The type that is being created by the client basically is a concrete class, which derives from a base class and also an interface (IMyMessage) and then places this on the MSMQ.
After some testing, if I remove the service known type attributes and just instead use say "string" instead, then it seems to open the host but faults (because the message type is not what it was expecting).
where am I going wrong?
On further testing I see that if I only specify the concrete type, it works.
This is not quite what I was expecting. how am I able to create it so that the service can take a known interface and classes which that interface has? The idea is for the client (using the same contract and classes) to send the message as "IMyMessage" and for the WCF service to pick that up as "IMyMessage" and go ahead and find out the type of message/object it is.
How?
Upvotes: 1
Views: 3258
Reputation: 65391
Your contract is an interface, but the definition within the contract must be concrete classes.
In your case it looks like you want to send over a list of things, those things could be different but they all support the same interface.
The problem is that when WCF deserialises what has been sent over the wire, it needs to deserialise it the a concrete type. If it just has an interface in the definition and 20 different types that implement that definition, it does not know what to do with it.
What you can do is have a base type that implements the interface, all your classes inherit from the base type and you use the base type in your contact.
Upvotes: 4