Currently nuts about Javascript, C# and Patterns

ComVisible class with a non ComVisible baseclass

In my previous post I was talking about using the WebBrowserControl in a WinForms application. I demonstrated how you can communicate to the JavaScript of the webpage loaded in the WebBrowserControl in your C# code and vice versa.

While using this code I ran into a problem myself. The Form which was made ComVisible had a baseclass which was not ComVisible. When I ran my code I had this great exception when calling the C# code from JavaScript:

NonComVisibleBaseClass was detected

A QueryInterface call was made requesting the default IDispatch interface of COM visible managed class ‘JYAG.WebControlInWinforms.GeekBrowser’. However since this class does not have an explicit default interface and derives from non COM visible class ‘JYAG.WebControlInWinforms.GeekBasePage’, the QueryInterface call will fail. This is done to prevent the non COM visible base class from being constrained by the COM versioning rules.

The simplest solution is to make the baseclass ComVisible just as well. But in my case it was not an option to expose the baseclass to Com-components. So what can we do to make this work without having to make the baseclass ComVisible. There are three easy steps to take to accomplish this.

Step 1 – Define a interface with the methods you’d like to call from JavaScript

First we define a Interface and put all the methods we want to reach through JavaScript in there. We make the interface ComVisible. I took the test-project of my previous post and added a IMapControlInteractable interface which contains just one method.

To use the Interface in combination with the ComVisible attribute and effectivly let the JavaScript communicate with the C# code we give the class the ClassInterfaceAttribute and specify the type at ‘none’.

[ClassInterface(ClassInterfaceType.None)]

Step 3 – Implement the Interface

The last thing we must do is implement the Interface. If we do so the code my look something like this.

//Make class visible for COM so we can set the ObjectForScripting
//Specify ClassInterfaceType.None to use the ComVisible Interface
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public partial class GeekBrowser : GeekBasePage, IMapControlInteractable
{

That’s all there is to it. Now our exception at runtime disappears and our code works. And our baseclass is not ComVisible.

Just your average geek?

Welcome to my blog.

This blog will mainly be used to tell you about all the nice things I learn in daily life which I want to share with all of you. Of course this will be about coding. C# code and Javascript, because that is what I am currently nuts about.