Silverlight and Flash/Flex RPC with the FluorineFx Silverlight library
The last post of the Silverlight series that should have been the first one…
Network Security Access Restrictions in Silverlight 2
If the case of RPC over HTTP the Silverlight 2 runtime will try to download a security policy file using the HTTP protocol. The runtime tries to download a Silverlight policy file with a name of “clientaccesspolicy.xml” at the root of the requested target domain using the HTTP protocol (it also accepts “crossdomain.xml” at the root of the requested target domain)
In our sample I’ve put the following clientaccesspolicy.xml file in the web site root:
<?xml version=”1.0″ encoding=”utf-8″?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers=”*”> <domain uri=”*”/> </allow-from> <grant-to> <resource path=”/” include-subpaths=”true”/> </grant-to> </policy> </cross-domain-access> </access-policy>
The ASP.NET application
The web application is taken form the FluorineFx samples [FluorineFx InstallDir]\Samples\Flex\Remoting\DataAccess and exposes a service returning a DataTable as strongly typed CustomerVO objects:
[DataTableType(“Flex.CustomerVO”)] [Description(“Filter customer by phone area code”)] public DataTable GetCustomers(string areaCode) { using (OleDbConnection connection = new OleDbConnection(GetConnectionString())) { OleDbCommand command = new OleDbCommand(“SELECT firstname, lastname, phone FROM [customer] WHERE phone LIKE ‘” + areaCode + “%’”, connection); connection.Open(); OleDbDataAdapter adapter = new OleDbDataAdapter(command); DataTable result = new DataTable(); adapter.Fill(result); return result; } }
The code snippet above retrieves a DataTable and instructs the gateway to return the result as a collection (ArrayCollection) of “Flex.CustomerVO” objects (the properties of the object will be the column names).
Creating the Silverlight project
Start Visual Studio 2008, create a new Silverlight Application (I’ve named it SilverlightApplication) a new web application to host the Silverlight client (the web application can be the same as the one exposing the remoting services).
Put the following XAML markup in the Page.xaml file:
<UserControl xmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data” x:Class=”SilverlightApplication.Page” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” Width=”400″ Height=”300″> <Grid x:Name=”LayoutRoot”> <Grid.RowDefinitions> <RowDefinition Height=”40″ /> <RowDefinition /> <RowDefinition Height=”80″ /> </Grid.RowDefinitions> <StackPanel Orientation=”Horizontal” HorizontalAlignment=”Left” Grid.Row=”0″> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width=”300″/> <ColumnDefinition Width=”100″/> </Grid.ColumnDefinitions> <TextBox x:Name=”txtSearch” Grid.Column=”0″ FontSize=”12″ Padding=”5″ Height=”26″ Margin=”0,0,5,0″/> <Button Content=”Get Customers” Padding=”5″ Margin=”0,0,0,0″ Height=”26″ Grid.Column=”1″ x:Name=”btnPopulate” Click=”Button_Click” /> </Grid> </StackPanel> <my:DataGrid x:Name=”customersDataGrid” IsReadOnly=”True” Grid.Row=”1″ RowHeight=”30″ AutoGenerateColumns=”True”> </my:DataGrid> <TextBox x:Name=”TxtLog” Width=”400″ VerticalScrollBarVisibility=”Visible” HorizontalScrollBarVisibility=”Visible” Grid.Row=”2″ /> </Grid> </UserControl>
In the Solution Explorer add a reference to FluorineFx.dll (note: we are adding the FluorineFx Silverlight client library to the Silverlight application and not the remoting gateway!). The assembly should be located in the “Bin\net\Silverlight2.0” folder.
Add the following code to the Page.xaml.cs code file:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using FluorineFx; using FluorineFx.Net; using FluorineFx.Messaging.Api; using FluorineFx.Messaging.Api.Service; using FluorineFx.AMF3; namespace SilverlightApplication { public partial class Page : UserControl { NetConnection _netConnection; public Page() { InitializeComponent(); // Create NetConnection client _netConnection = new NetConnection(); _netConnection.ObjectEncoding = ObjectEncoding.AMF3; _netConnection.NetStatus += new NetStatusHandler(_netConnection_NetStatus); // Put your gateway url here _netConnection.Connect(“http://localhost:1781/SilverlightApplicationWeb/Gateway.aspx”); } void _netConnection_NetStatus(object sender, NetStatusEventArgs e) { string level = e.Info[“level”] as string; if (level == “error”) { //received an error Log(“Error: ” + e.Info[“code”] as string); } if (level == “status”) { Log(“Status: ” + e.Info[“code”] as string); } } private void Button_Click(object sender, RoutedEventArgs e) { _netConnection.Call(“ServiceLibrary.MyDataService.GetCustomers”, new GetCustomersHandler(this), new object[] { txtSearch.Text }); } public void Log(string msg) { Dispatcher.BeginInvoke(delegate() { TxtLog.Text += msg + “\r\n”; }); } public void Bind(IList list) { Dispatcher.BeginInvoke(delegate() { customersDataGrid.ItemsSource = list; }); } } public class GetCustomersHandler : IPendingServiceCallback { Page _page; public GetCustomersHandler(Page page) { _page = page; } public void ResultReceived(IPendingServiceCall call) { object result = call.Result; //DataAccess sample sends back an ArrayCollection (AMF3) ArrayCollection items = result as ArrayCollection; foreach (object item in items) { Flex.CustomerVO customer = item as Flex.CustomerVO; _page.Log(customer.ToString()); } _page.Bind(items); } } }
Then add a CustomerVO class to the Silverlight application (note the namespace is called Flex so class mapping will work automatically)
using System; namespace Flex { public class CustomerVO { string _firstname; public string firstname { get { return _firstname; } set { _firstname = value; } } string _lastname; public string lastname { get { return _lastname; } set { _lastname = value; } } string _phone; public string phone { get { return _phone; } set { _phone = value; } } } }
Run the application.
Here is a screenshot of the running application
Update: the Silverlight library is available for download in the latest FluorineFx version

