0 votes
by (140 points)


I am trying out Rebex HTTPs for our Compact Framework.Net app. The app makes extensive use of WCF calls using proxies generated by the CF.Net version of svcutil.

I am using the HttpRequestCreator.Register() approach for registering the Rebex library. However, the WCF calls are getting an error inside the HTTPChannelFactory class with an InvalidCastException. The .Net HTTPChannelFactory.GetWebRequest method is expecting the return type of GetWebRequest to be HttpWebRequest. Since Rebex returns a HttpRequest, this is resulting in the casting exception. I am adding the stack trace at the end of this message.

Is there any alternative way of using HttpChannelFactory with Rebex, or plans to add support for this in the future ?


Subha Tarafdar.

Stack Trace returning InvalidCastException: 
at System.ServiceModel.Channels.HttpChannelFactory.GetWebRequest(EndpointAddress to, Uri via, TimeSpan timeout)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.GetWebRequest(EndpointAddress to, Uri via, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.HttpsChannelFactory.HttpsRequestChannel.GetWebRequest(EndpointAddress to, Uri via, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message)
at Microsoft.Tools.ServiceModel.CFClientBase`1.getReply(Message msg)
at Microsoft.Tools.ServiceModel.CFClientBase`1._Invoke[TREQUEST,TRESPONSE](CFInvokeInfo info, IsAvailableForSyncingRequest request)
at Microsoft.Tools.ServiceModel.CFClientBase`1.Invoke[TREQUEST,TRESPONSE](CFInvokeInfo info, IsAvailableForSyncingRequest request)
Applies to: Rebex HTTPS
by (64.5k points)
Hi, the problem is already solved. Please see my comment from 2017-05-26:
by (3.9k points)
You are talking about Rebex.Ftp, but this question is related to Rebex.Http.

Please, ask new question and describe your issue.
Are you using Rebex.Ftp in WCF? How?
Attach exception details as well please.
by (64.5k points)
Oh, I was confused by mentioning Rebex.Ftp.

Ok, please download the custom WCF binding implementation from: https://www.rebex.net/getfile/b541b39f9c334407b148786cd6fbdbc4/RebexWcfBinding.zip

Include the classes in your project and use it like this:

    // initialize Rebex WCF binding
    var binding = new Rebex.Samples.WcfBinding();

    // just for testing purposes, skip server's certificate validation
    // Do not use this in production code!
    binding.RequestCreator.Settings.SslAcceptAllCertificates = true;

    // use your WCF service (e.g. GeocodeServiceClient in my case)
    GeocodeServiceClient client = new GeocodeServiceClient(binding,
        new System.ServiceModel.EndpointAddress("https://address/geocodeservice.svc"));
by (3.9k points)
edited by
It seems that the server is closing connection for some reason. please send a communication log in debug level to support@rebex.net for analysis. it cxan be done like this:

binding.RequestCreator.LogWriter = new Rebex.FileLogWriter(@"/log.txt", Rebex.LogLevel.Debug);

1 Answer

0 votes
by (64.5k points)
edited by


The custom WCF binding implementation discussed below in comments is already available at https://www.rebex.net/getfile/b541b39f9c334407b148786cd6fbdbc4/RebexWcfBinding.zip

You can use it like this:

new MyServiceClient(new WcfBinding(), new EndpointAddress("https://..."))

To configure various properties, use WcfBinding.RequestCreator property.

Original answer:


you are right. The problem is caused by impossibility to cast Rebex class HttpRequest into system class HttpWebRequest.

Unfortunately, the HttpWebRequest class on .NET CF has no public or protected constructor, so we cannot derive from it. We can derive only from WebRequest class.

Also the HttpChannelFactory class is written in a way it can use HttpWebRequest class only.

We are not familiar with WCF, but I used to create some Web References. There you get a partial class XyzService, which inherits from System.Web.Services.Protocols.SoapHttpClientProtocol. Using partial keyword, you can simply reimplement some functionality which remains unchanged even when you recreate the web reference.

Try to look at some way to reimplement CFClientBase1.Invoke or CFClientBase1.getReply or RequestChannel.Request or inject your implementation of HttpChannelFactory which doesn't require HttpWebRequest class only or something similar.

For example in my VB.NET project I do similar this way:

Partial Public Class MyService

    Protected Overrides Function GetWriterForMessage(message As SoapClientMessage, bufferSize As Integer) As XmlWriter
        ' inject code for signing the request here
        Return New SigningXmlTextWriter(MyBase.GetWriterForMessage(message, bufferSize))
    End Function

End Class

I implemented SigningXmlTextWriter class to sign the SOAP request message with an X509 certificate.

If you send us your project at support@rebex.net (so we can reproduce the issue) we will look at it and hopefully find a solution to solve this issue.

by (140 points)
Thanks for the suggestion. I will look into whether the WebReference proxies will work with our solution.
by (64.5k points)
I finally completed custom Binding with all necessary features. You can download it from http://www.rebex.net/getfile/b541b39f9c334407b148786cd6fbdbc4/RebexWcfBinding.zip

You can use it like this:

  new MyServiceClient(new WcfBinding(), new EndpointAddress("https://..."))

To configure various properties use WcfBinding.RequestCreator property. Especially, on .NET CF use only for testing purposes:
  binding.RequestCreator.Settings.SslAcceptAllCertificates = true;
by (140 points)
Thanks a lot ! I will try it out and let you know.
by (140 points)
I have tried it out, it is working fine so far. There are some configurations like WCF maximum message size, etc which I will need to look at, but the WCF calls in general are working.
by (64.5k points)
Great. Thank you for letting us know.