Bug 16967 - ChannelFactory<IRequestChannel> does not work
Summary: ChannelFactory<IRequestChannel> does not work
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: WCF assemblies (show other bugs)
Version: master
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-12-26 05:59 UTC by Michael Ayvazyan
Modified: 2014-06-09 22:19 UTC (History)
2 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Michael Ayvazyan 2013-12-26 05:59:44 UTC
We implemented WCF Routing Service. It implements universal contract and is capable to deliver messages to the "real" services.
It is working fine on .NET 4.5 (it was working fine on .NET 4.0 as well).
Now I’m trying to run it under Mono. Our Routing Service fails to deliver messages to the “real” services with the following exception:
Unable to process message System.Reflection.TargetException: Object of type 'System.ServiceModel.MonoInternal.ClientRuntimeChannel' doesn't match target type 'MyNamespace.IUniversalListenerService'
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
  at System.ServiceModel.ClientRealProxy.DoInvoke (IMessage inputMessage) [0x00000] in <filename unknown>:0
  at System.ServiceModel.ClientRealProxy.Invoke (IMessage inputMessage) [0x00000] in <filename unknown>:0
  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x00000] in <filename unknown>:0

Universal contract we are using:
[ServiceContract(Namespace = Namespaces.LegacyV1)]
    public interface IUniversalListenerService
    {
        [OperationContract(Action = "*", ReplyAction = "*")]
        Message ProcessMessage(Message message);
    }

WCF Routing Service code 
Message messageToSend; // message we need to deliver to the “real” service
var factory = new ChannelFactory<IUniversalListenerService>(service);
// had to comment this line cause it doesn't supported by mono
//factory.Endpoint.Behaviors.Add(new MustUnderstandBehavior(false));
IEsbRouterService proxy = factory.CreateChannel();
var result = proxy.ProcessMessage(messageToSend); // this call results in above exception

Would you please suggest how can I rework this code to work under Mono?
Any help will be greatly appreciated!

I'm using "Mono JIT compiler version 3.3.0 (master/6cd4ddc)"

Maybe I can call the ClientRuntimeChannel.BeginRequest method using reflection to do that?
ClientRuntimeChannel.cs
internal IAsyncResult BeginRequest (Message msg, TimeSpan timeout, AsyncCallback callback, object state)
                {
                        return requestDelegate.BeginInvoke (msg, timeout, callback, state);
                }
Comment 1 Michael Ayvazyan 2013-12-26 08:56:52 UTC
Did some more research looks like it's about the following lines of code.
Cause in our case the method we call ("ProcessMessage") is different from the actual method we are going to execute on a "real" service.
Still don't have a clue on how to workaround this... 

IMessage DoInvoke (IMessage inputMessage)
                {
                        var inmsg = (IMethodCallMessage) inputMessage;
                        var od = channel.Contract.Operations.FirstOrDefault (o => inmsg.MethodBase.Equals (o.SyncMethod) || inmsg.MethodBase.Equals (o.BeginMethod) || inmsg.MethodBase.Equals (o.EndMethod));
                        if (od == null) {
                                // Then IContextChannel methods.
                                var ret = inmsg.MethodBase.Invoke (channel, inmsg.InArgs);
                                return new ReturnMessage (ret, null, 0, null, inmsg);
                        } else {


https://github.com/mono/mono/blob/master/mcs/class/System.ServiceModel/System.ServiceModel/ClientRealProxy.cs?source=cc
Comment 2 Michael Ayvazyan 2013-12-26 10:52:48 UTC
How to reproduce:

var factory = new ChannelFactory<IRequestChannel>(serviceEndpoint);
var channel = factory.CreateChannel();
factory.Open();
IRequestChannel channel = factory.CreateChannel();
channel.Open();
/*
The following call will result in "Object of type 'System.ServiceModel.MonoInternal.ClientRuntimeChannel' doesn't match target type 'System.ServiceModel.Channels.IRequestChannel'"
*/
Message result = channel.Request(messageToSend);
Comment 3 Michael Ayvazyan 2013-12-26 11:49:39 UTC
Sorry I was wrong. Exception occurs earlier during factory.Open() call.

var factory = new ChannelFactory<IRequestChannel>(serviceEndpoint);
factory.Open();
/*
The following call will result in "Object of type
'System.ServiceModel.MonoInternal.ClientRuntimeChannel' doesn't match target
type 'System.ServiceModel.Channels.IRequestChannel'"
*/
factory.Open();
Comment 4 Michael Ayvazyan 2013-12-27 14:36:05 UTC
I did some more investigation.
If I'm creating factory using below code. It seems to work better.
But fails with time out error.
PLease not that if I'm sending message directly to the "real" service. It's working fine. But if I'm sending message using ChannelFactory in my router service I get below time out.

var factory = new ChannelFactory<IUniversalListenerService>(serviceEndpoint.Binding, serviceEndpoint.Address);
factory.Open();
var channel = factory.CreateChannel();
Message result = channel.ProcessMessage(messageToSend);

Channel failure System.TimeoutException: The operation has timed-out.
  at System.ServiceModel.Channels.HttpRequestChannel+HttpChannelRequestAsyncResult.WaitEnd () [0x00000] in <filename unknown>:0
  at System.ServiceModel.Channels.HttpRequestChannel.EndRequest (IAsyncResult result) [0x00000] in <filename unknown>:0
  at System.ServiceModel.Channels.HttpRequestChannel.Request (System.ServiceModel.Channels.Message message, TimeSpan timeout) [0x00000] in <filename unknown>:0
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Request (System.ServiceModel.Channels.Message msg, TimeSpan timeout) [0x00000] in <filename unknown>:0
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Request (System.ServiceModel.Description.OperationDescription od, System.Object[] parameters) [0x00000] in <filename unknown>:0
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.DoProcess (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00000] in <filename unknown>:0
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Process (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00000] in <filename unknown>:0
Comment 5 Shane van Wyk 2014-06-09 22:19:34 UTC
I'm trying to post to a server as well, running on mono 3.2.8.

Getting the same time-out exception.

Basically calling client.Opperation(); and it just times out.

Any ideas to why this is happening?

Note You need to log in before you can comment on or make changes to this bug.