I've been working with WCF the last two days and it was going very well with the server and client both on my development machine. Now that I am trying to do some distributed testing with the client on another machine on the network I've started running into problems. Right now the error I am getting is:
The message with Action 'http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
As this is already a massive learning experience (I haven't done any remoting, RPC, et al before) I want to continue developing the learning tool and revisit security when I'm finished (I have no intention of building anything that will actually get used without the proper security best practices).
Notes:
- I don't have a configuration file setup for WCF - I'm doing everything programmatically.
- My network is not part of a domain so the default security settings were not working for me (using net.tcp).
- I'm using '.Net 3.5'.
My server is created like this:
var svh = new ServiceHost(_serviceImplementation);
var binding = new NetTcpBinding();
binding.ReaderQuotas.MaxArrayLength = 2000000;
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
svh.AddServiceEndpoint(_serviceInterface, binding, string.Format("net.tcp://{0}:{1}", _endPoint.Address, _endPoint.Port));
_stopFlag = new AutoResetEvent(false);
svh.Open();
_stopFlag.WaitOne();
And my client is created like this:
var binding = new NetTcpBinding();
binding.ReaderQuotas.MaxArrayLength = 2000000;
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
var scf = new ChannelFactory<IUserInputContract>(binding, "net.tcp://192.168.0.42:8001");
_uiUpdateServer = scf.CreateChannel();
And my contract (which is just in a class library that is added as a reference to both the client and server) is:
[ServiceContract(ProtectionLevel = ProtectionLevel.None)]
public interface IWindowUpdateContract {
[OperationContract]
void UpdateWindowFrames(WindowFrame frame);
[OperationContract]
void WindowHasClosed(IntPtr hwnd);
}
I feel that the binding and contract setup I have done should make them identical and I shouldn't have this problem (and security should be turned off). I just don't know where to go now.