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)
commented Oct 12 by Venkateshb7 (100 points)
Hi,

I too facing the same problem.. please tell me what and all required to resolve this as i dont have much experience on this area.
commented Oct 12 by Lukas Matyska (39,480 points)
Hi, the problem is already solved. Please see my comment from 2017-05-26:
http://forum.rebex.net/7041/rebex-https-support-for-proxies-using-httpchannelfactory?show=7111#c7111
commented Oct 13 by Venkateshb7 (100 points)
edited Oct 13 by Venkateshb7
I read the entire comments thread but unable to get the right solution.

Please share us sample client app which will use proxy classes and how we are integrating the classes you shared in the above url in client application. We are using Rebex.ftp from many years and now we need support for SHA-2 based certificates in wince devices. please help us as we are in middle of some certifications.
commented Oct 13 by stepantalalayev (940 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.
commented Oct 13 by Venkateshb7 (100 points)
I am just telling you that we already using licensed Rebex dlls in our project. I dont have any problem with Rebex.ftp.dll.

Now my question is about Rebex.https dll only. this dll I downloaded recently from trial pack and trying to integrate. but i got the same error what we are discussing in this thread(InvalidcastException) after using the following code to register rebex dlls.  

  var creator = new HttpRequestCreator();
                    creator.Register();

whenever i am calling any web service method i am getting the following exception
Exception is:
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)
commented Oct 13 by Lukas Matyska (39,480 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"));
commented Oct 13 by Venkateshb7 (100 points)
Thanks.. Will try and come back to you.

1 Answer

0 votes
answered May 3 by Lukas Matyska (39,480 points)
edited Oct 12 by Lukas Matyska

UPDATE:

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:

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 (39,480 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 (39,480 points)
Great. Thank you for letting us know.
...