Introduction
My original task was to create a .NET wrapper class for an existing native C++ code and expose to web page as in Active X but in .NET and set up an environment in which the web page can communicate with native code and vice-versa. This task isn't finished yet, but I have found a solution for intercommunication between the client side web page and a .NET user control. In this article, I will show you how to place a C# user control on the Internet Explorer web page (client side) and how the user control can communicate with the web page and back. In this way, rich client side applications can be built in .NET.
Background
In Internet Explorer, we can embed the user control with <object>
tag. The user control will be able to fire an event which can be caught by JavaScript on the web page and the JavaScript can call the user control code. The user control needs to grant privileges with caspol.exe. Instead of adding full trust to the user control, I will give for the whole site (there can be a security leak in some cases) because from .NET 2.0, there is no .NET administrator and global assembly cache if the user does not want to download the platform SDK, just the framework.
Using the Code
I have installed Visual studio 2008 with .NET Framework 3.5, and without platform SDK, so I haven't added gacutil.exe to cache my assembly.
Start Visual Studio 2008 with C# installed and press File -> New Project. On the left side, click on C#. Now on the right side, select the WindowsFormsControlLibrary
. I have renamed my WindowsFormsControlLibrary1
to UserControl3
(to make a different name from my other work), that changes the default namespace from WindowsFormsControlLibrary1
to UserControl3
- nothing else. Now there are two samples on the web which are almost working, this one and an advanced one (you need to delete the & n b s p characters from the source code sample) there are descriptions which are the events and the delegates. There are other samples with communication here. Don't forget the need to grant security privileges to user controls for it to work. Here is a description about that. Shortly, the web page needs to be added to Trusted Sites, for this, start Internet Explorer 6 -> Tools -> Internet Options at the Security tab click on the Trusted Sites, then sites button, then add the site here (I have added my LAN IP here - http://193.231.162.210). Now add trusted site for Internet Explorer, but we need to do it for .NET too:
CasPol.exe -q -m -ag All_Code -zone Intranet FullTrust
CasPol.exe -q -m -ag All_Code -zone Trusted FullTrust
Caspol.exe is located at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 by default in Windows XP and .NET Framework 3.5, and isn't in PATH system variable!
Now right click on the project in the Visual Studio solution explorer window and select properties, click on the Build tab and check the "Register for Com interop". On the solution explorer window, select the expand the properties node under the project and double click at AssemblyInfo.cs. You should have:
[assembly: ComVisible(true)]
and a guid generated:
[assembly: Guid("936987f7-536b-4a0c-b8f2-37e387d97108")]
Go in design mode and add a button to the user control. I have renamed the button to btFireEvent
and I had set the text: Fire Javascript Event. Double click on the button (it will generate the correct handler method). Now complete the code from the samples and your source code in the UserControl1.cs. After that, this file needs to look like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace UserControl3
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface UserControl1Events
{
[DispId(0)]
void SubmitClicked();
}
public delegate void SubmitClickedHandler();
[ComSourceInterfaces(typeof(UserControl1Events))]
public partial class UserControl1 : UserControl
{
public event SubmitClickedHandler SubmitClicked;
protected virtual void OnSubmitClicked()
{
if (SubmitClicked != null)
SubmitClicked();
}
public UserControl1()
{
InitializeComponent();
}
public string WhatTimeIsIt(string msg) {
MessageBox.Show(msg,"Inside C#");
return DateTime.Now.ToString();
}
private void btFireEvent_Click(object sender, EventArgs e)
{
OnSubmitClicked();
}
}
}
Build it! Under the bin/Debug dir, the desired DLL, UserControl3.dll, has to be there.
Now Write the .html Part
On my webserver (Apache 2.0) documents root (htdocs), I have created a folder with the name:
tutorial. Copy
UserControl3.dll to this folder. Make a new
.txt file. Enter this text there:
<html>
<body>
<object id="SimpleUserControl"
classid="http://193.231.162.210/tutorial/UserControl3.dll#UserControl3.UserControl1"
height="150" width="150" >
</object>
<input type="button" value="What time is it?" önclick="DoWhatTimeIsIt();" />
</body>
<script language="javascript">
function DoWhatTimeIsIt() {
alert(document.SimpleUserControl.WhatTimeIsIt('I am Szabi on Javascript'));
}
</script>
<script for="SimpleUserControl" event="SubmitClicked" language="javascript">
alert("Hello from C# fired event");
</script>
</html>
Where you should change 193.231.162.210 to your local IP or localhost or 127.0.0.1 and the tutorial to the folder name which is created in the previous step.
Points of Interest
I hope this sample is working for you too. I wish to receive posts with how to pack / deploy multiple managed .dll -s ( and one of them is native C++ code).
I have tried with:
<link rel="Configuration" href="/path/to/MyControl.config"/>
This is explained here.
But with .NET 3.5, in my config file I can't find HttpForbiddenHandler
and can't set up the config file like this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="blsTree" culture="neutral"
publicKeyToken="007a0b78_bf42c201"/>
<codeBase version="1.0.955.24881"
href="http://localhost/blstree.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>