Walkthrough: Calling Managed Code from JavaScript

Microsoft Silverlight will reach end of support after October 2021. Learn more.

This topic shows how to call managed code from JavaScript in a Web page that includes the Silverlight plug-in. This gives client script access to the extensive .NET Framework features that are available in managed code, without requiring a round trip to the Web server.

Using client script to call managed code in a Silverlight-based application involves the following tasks:

  • Handling the Startup event of the XAML Application object in order to bind client script to the XAML code and to register a managed-code class as a scriptable object.

  • Making members of a managed-code class accessible to script by using the Scriptable attribute.

  • Invoking managed-class methods and accessing managed-class properties from client script.

NoteNote:

Silverlight for Windows Phone Silverlight for Windows Phone does not support the HTML Bridge feature.

Prerequisites

You need the following components to complete this walkthrough:

  • Silverlight 5.

  • Silverlight Tools for Visual Studio 2010.

  • Microsoft Visual Studio 2010.

All of the Silverlight software is available from the Silverlight download site.

Creating a Silverlight Project and Test Page

The first step is to create a Silverlight project and a test page.

To create a Silverlight project and test page

  1. Create a new Silverlight Application project named HB in Visual Basic or Visual C#. Select the Host the Silverlight application in a new Web site option. For more information, see How to: Create a New Silverlight Project.

  2. Open HBTestPage.aspx in Source view and find the form element that contains the Silverlight control. 

  3. Change the height style property of the form element from 100% to 10%.

  4. After the closing </form> tag, add an HTML input text element.

  5. Set the following properties of the input text element:

    • id: "Text1"

    • disabled: "disabled"

    • value: "My Initial Value"

    The following example shows the markup for the input text element.

    <input type="text" id="Text1" disabled="disabled"
      value="My Initial Value" />
    
  6. Press F5 to build and run the solution.

    The page is displayed. The input text element is disabled.

  7. Close the browser.

Binding the Client Script to XAML Code

An App.xaml file is automatically created when you create a Silverlight project. The code-behind file for the App.xaml file (App.xaml.cs for C# and App.xaml.vb for Visual Basic) defines an App class that contains an Application_Startup method. You can write code in this method to bind or establish a connection between your Web page and a managed class.

To bind client script to the XAML code

  1. Open the code-behind class file for the App.xaml file.

  2. At the top of the file, add a using or Imports statement to import the System.Windows.Browser namespace.

  3. Add code to the Application_Startup method that performs the following tasks:

    The following example shows how to perform these tasks.

    'HtmlDocument requires Imports System.Windows.Browser  
    Dim doc As HtmlDocument = HtmlPage.Document
    doc.GetElementById("Text1").SetProperty("disabled", False)
    doc.GetElementById("Text1").SetAttribute("value", _
           "This text set from managed code.")
    
    // HtmlDocument requires using System.Windows.Browser; 
    HtmlDocument doc = HtmlPage.Document;
    //Enable the HTML textbox on the page and say hello
    doc.GetElementById("Text1").SetProperty("disabled", false);
    doc.GetElementById("Text1").SetAttribute("value", 
        "This text set from managed code.");
    
  4. Press F5 to run the application.

    This time, the input button is enabled and its text is "This text set from managed code".

  5. In the HB project, add a new class and name it MyScriptableManagedType.

  6. In the class, add the following members:

    • A MyToUpper method that returns a string in uppercase after invoking the ToUpper method on it.

    • A Name property that returns the value of a _name member variable.

    Mark both members with the ScriptableMemberAttribute attribute, which is required in order to expose the members to client script.

    The following example shows MyScriptableManagedType class.

    ' MyScriptableManagedType.vb
    
    Imports System.Windows.Browser
    '<ScriptableType()> _
    Public Class MyScriptableManagedType
       Dim _name As String
    
       <ScriptableMember()> Public Function MyToUpper(ByVal str As String) As String
          Return str.ToUpper
       End Function
    
       <ScriptableMember()> Public Property Name() As String
          Get
             Return _name
          End Get
          Set(ByVal value As String)
             _name = value
          End Set
       End Property
    
    End Class
    
    // MyScriptableManagedType.cs
    using System.Windows.Browser;
    
    namespace HB {
        public class MyScriptableManagedType {
            [ScriptableMember()]
            public string MyToUpper(string str) {
                return str.ToUpper();
            }
    
            [ScriptableMember()]
            public string Name { get; set; }
        }
    }
    
    
  7. Build the solution to confirm that there are no errors.

Registering Managed Code for Client Script Access

The next step is to create a scriptable managed-code object that can be called from client script.

To register and access a class as a scriptable object

  1. Open the code-behind class for the App.xaml file.

  2. At the end of the Application_Startup method, call the HtmlPage.RegisterScriptableObject method in order to register the MyScriptableManagedType class as a scriptable object.

    The following example shows how to register the class.

    'Set up some scriptable managed types for access from Javascript.
    Dim smt As MyScriptableManagedType = New MyScriptableManagedType()
    HtmlPage.RegisterScriptableObject("mySLapp", smt)
    
    //Set up some scriptable managed types for access from Javascript.
    MyScriptableManagedType smt = new MyScriptableManagedType();
    
    HtmlPage.RegisterScriptableObject("mySLapp", smt);
    
  3. Build the solution to confirm that there are no errors.

  4. Open the HBTestPage.aspx file in Source view.

  5. Just before the closing </head> tag, create a script element.

  6. In the script element, create a pluginLoaded function that will be called when the Silverlight application has finished loading.

  7. In the pluginLoaded function, perform the following tasks:

    • Get a reference to the Silverlight control that contains the managed object.

    • Call the MyToUpper scriptable method that you created earlier. Use a fully qualified call that takes the form SilverlightControl.Content.scriptableObject.MyToUpper(string).

    The following example shows how to perform these tasks.

    <script type="text/javascript">
    var slCtl = null;
      function pluginLoaded(sender,args){
         slCtl  = sender.getHost();
         alert(slCtl.Content.mySLapp.MyToUpper("Test String"));
    }
    </script>
    
  8. In the Silverlight object markup, add an onLoad attribute that has the value "pluginLoaded".

    The following example shows the HTML markup for the Silverlight control reference.

    <object data="data:application/x-silverlight-2," 
        type="application/x-silverlight-2" width="100%" height="100%">
      <param name="source" value="ClientBin/HB.xap"/>
      <param name="onerror" value="onSilverlightError" />
      <param name="onLoad" value="pluginLoaded" />
      <!-- ... -->
    </object>
    
  9. Press F5 to run the page.

    A message box displays "TEST STRING".

Testing Client-Script Access to Managed Code

You can now create client script that lets you test the scriptable object.

To get and set managed-code property values using JavaScript

  1. In the HBTestPage.aspx file, after the input text element you added earlier, add an HTML button named Button1 with a value of "Test set/get".

  2. In the HTML button, bind its onclick event to the Button1_onclick method. (You will create this method in the next step.)

    The following example shows the HTML markup for the button.

    <input id="Button1" type="button" value="Test set/get" 
      onclick="return Button1_onclick()" />
    
  3. In the script element, add the following Button1_onclick method:

    The variable slCtl is the Silverlight control that you initialized in the previous procedure. mySLapp is the scriptable object initialized previously. Name is a property in the scriptable object.

    function Button1_onclick() {
        slCtl.Content.mySLapp.Name = navigator.appName;
        alert(slCtl.Content.mySLapp.Name);
    } 
    
  4. Press F5 to run the page.

  5. In the message box that displays "TEST STRING", click OK.

  6. Click the Test set/get button.

    A message box displays the name of your browser.

Example

The following example shows the code for the test page (HBTestPage.aspx), the MyScriptableManagedType class, and the App.xaml code-behind.

Code

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>HB</title>
    <style type="text/css">
    html, body {
        height: 100%;
        overflow: auto;
    }
    body {
        padding: 0;
        margin: 0;
    }
    #silverlightControlHost {
        height: 100%;
        text-align:center;
    }
    </style>
    <script type="text/javascript">
        var slCtl = null;
        function pluginLoaded(sender) {
            slCtl = sender.getHost();
            alert(slCtl.Content.mySLapp.MyToUpper("Test String"));
        }
        function Button1_onclick() {
            slCtl.Content.mySLapp.Name = navigator.appName;
            alert(slCtl.Content.mySLapp.Name);
        }     
    </script>
</head>
<body>
    <form id="form1" runat="server" style="height:10%">
    <div id="silverlightControlHost">
        <object id="sl" data="data:application/x-silverlight-2," 
            type="application/x-silverlight-2" width="100%" height="100%">
            <param name="source" value="ClientBin/HB.xap"/>
            <param name="onLoad" value="pluginLoaded"/>
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="4.0.60129.0" />
            <param name="autoUpgrade" value="true" />
            <a href="https://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.60129.0" 
                style="text-decoration:none">
                <img src="https://go.microsoft.com/fwlink/?LinkId=161376" 
                    alt="Get Microsoft Silverlight" style="border-style:none"/>
            </a>
        </object>
        <iframe id="_sl_historyFrame" 
            style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
    </div>
    </form>
    <input type="text" id="Text1" disabled="disabled"
        value="My Initial Value" />
    <input id="Button1" type="button" value="Test set/get" 
        onclick="return Button1_onclick()" />
  </body>
</html>
' MyScriptableManagedType.vb

Imports System.Windows.Browser
'<ScriptableType()> _
Public Class MyScriptableManagedType
   Dim _name As String

   <ScriptableMember()> Public Function MyToUpper(ByVal str As String) As String
      Return str.ToUpper
   End Function

   <ScriptableMember()> Public Property Name() As String
      Get
         Return _name
      End Get
      Set(ByVal value As String)
         _name = value
      End Set
   End Property

End Class
// MyScriptableManagedType.cs
using System.Windows.Browser;

namespace HB {
    public class MyScriptableManagedType {
        [ScriptableMember()]
        public string MyToUpper(string str) {
            return str.ToUpper();
        }

        [ScriptableMember()]
        public string Name { get; set; }
    }
}

Imports System.Windows.Browser
Partial Public Class App
    Inherits Application

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
        Me.RootVisual = New Page()
        'HtmlDocument requires Imports System.Windows.Browser  
        Dim doc As HtmlDocument = HtmlPage.Document
        doc.GetElementById("Text1").SetProperty("disabled", False)
        doc.GetElementById("Text1").SetAttribute("value", _
               "This text set from managed code.")
        'Set up some scriptable managed types for access from Javascript.
        Dim smt As MyScriptableManagedType = New MyScriptableManagedType()
        HtmlPage.RegisterScriptableObject("mySLapp", smt)
    End Sub

End Class
// App.xaml.cs
using System.Windows;
using System;

using System.Windows.Browser;

namespace HB {
    public partial class App : Application {

        public App() {
            this.Startup += this.Application_Startup;

            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e) {
            // Load the main control
            this.RootVisual = new Page();

            // HtmlDocument requires using System.Windows.Browser; 
            HtmlDocument doc = HtmlPage.Document;
            //Enable the HTML textbox on the page and say hello
            doc.GetElementById("Text1").SetProperty("disabled", false);
            doc.GetElementById("Text1").SetAttribute("value", 
                "This text set from managed code.");
            //Set up some scriptable managed types for access from Javascript.
            MyScriptableManagedType smt = new MyScriptableManagedType();

            HtmlPage.RegisterScriptableObject("mySLapp", smt);
        }
    }
}