Rebex HTTPS - support for WCF proxies using HttpChannelFactory

0 votes
asked May 3 by subha (140 points)

Hello,

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 ?

Thanks.

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)

1 Answer

0 votes
answered May 3 by Lukas Matyska (36,240 points)

Hello,

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.

commented May 23 by subha (140 points)
Thanks for the suggestion. I will look into whether the WebReference proxies will work with our solution.
commented May 26 by Lukas Matyska (36,240 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;
commented May 26 by subha (140 points)
Thanks a lot ! I will try it out and let you know.
commented Jun 6 by subha (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.
commented Jun 6 by Lukas Matyska (36,240 points)
Great. Thank you for letting us know.
...