Wednesday 12 August 2009

Silverlight 3 and Web Service

The most effective way for a Silverlight application to tap into server-side code is through web services. The basic idea is simple—you include a web service with your ASP.NET website or add reference to a standalone web service, and your Silverlight application calls the methods in that web service. Silverlight applications can call traditional ASP.NET web services (.asmx services) as well as the WCF services, which are the newer standard.

Creating a Web Service


There are 2 ways how to create a Web Service in Visual Studio:
  1. Add New WCF Service Application Project (File - New Project - WCF Service Application)
  2. Add New Item - Silverlight-Enabled WCF Service (In the Solution Explorer on your web application project right click and select from the content menu Add - New Item - Silverlight-Enabled WCF Service
As I mentioned in my previous post, if you're about to create a standalone WCF Service Application you'll also needed to create and copy to your web root directory clientAccessPolicy.xml and crossDomain.xml files. These two files take care about accessibility of the Web Service.

When the project "included" WCF Service is created, you don't need to think about accessibility files. Visual Studio automatically configures the Web Service to be accessible for the Silverlight application.

When you create a web service, Visual Studio, creates an Interface and Implementation files, namely as defaults: IService1.vb and Service1.svc.

All functions/subs definitions you create in the Interface file (IService1.vb) - make sure you Imports System.ServiceModel - have to start with <OperationContract()>
WCF Service doesn't support all object types to return results from functions, expect of some defaults such as Integer, String. Non supported object have to be implemented via class. Each class definition has to start with <DataContract()> and all property within a class has to start with <DataMember()>

Example of IService1.vb
Imports System.ServiceModel
<ServiceContract()> _
Public Interface IService1
<OperationContract()> _
Function GetUsers() As List(Of user)
End Interface
<DataContract()> _
Public Class user
Private _uId As Integer
Private _firstName As String
Private _lastName As String
<DataMember()> _
Public Property uId() As Integer
Get
Return _uId
End Get
Set(ByVal value As Integer)
_uId = value
End Set
End Property
<DataMember()> _
Public Property firstName() As String
Get
Return _firstName
End Get
Set(ByVal value As String)
_firstName = value
End Set
End Property
<DataMember()> _
Public Property lastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal usrId As Integer, _
ByVal
uFirstName As String, ByVal uLastName As String)
Me.uId = usrId
Me.firstName = uFirstName
Me.lastName = uLastName
End Sub

Very important

If you'd like to use the web service with your Silverlight application, you must modify the web service's Web.Config file and change service endpoint binding to "basicHttpBinding". That's because the Silverlight works only with this one.

To edit this value, open the web service's Web.Config file and scroll almost at the very end of the file. You have to search for these tags:

<system.serviceModel>
<services>
<service name=...

under the <service> tag you'll find <endpoint address=... tag. Edit this tag's binding value to "basicHttpBinding"

Example - before update:

<system.serviceModel>
<services>
<service name="WcfService.Service1"
behaviorConfiguration="WcfService.Service1Behavior">
<endpoint address="" binding="wsHttpBinding"
contract="WcfService.IService1">

after update:

<system.serviceModel>
<services>
<service name="WcfService.Service1"
behaviorConfiguration="WcfService.Service1Behavior">
<endpoint address="" binding="basicHttpBinding"
contract="WcfService.IService1">

Note: Before you publish your Silverlight application to the IIS, make sure you modified the ServiceReferences.ClientConfig file located in your Silverlight application folder. Only one but most important change is required - modify WCF service's endpoint address to the one on which the WCF service to be accessible on the Internet. By default, Visual Studio set up this address for running the web application in development environment, such as <endpoint address="http://localhost:49249/SilverlightApplication.Web/Service.svc".
Suppose, your WCF service is published on Default Web Site\WCFService folder, so the "real" service address will be http://localhost/WCFService/Service.svc therefore service's endpoint address in ServiceReferences.ClientConfig file should looks like:
<endpoint address="http://localhost/WCFService/Service.svc"
Please refer to Publish Silverlight 3 on IIS 7.0/7.5 for more information.

And finally
Whatever service creation way you choose you'll need to add a web service reference to your Silverlight application.

Adding a web service reference is easy. Just, in the Solution Explorer right click on your Silverlight application and from the content menu select "Add Service Reference". In the opened pop-up window (Add Service Reference) fill-up the "Address" text box with the service URL (if you're about to add reference to a standalone service already published on the Web) or click "Discover" button and Visual Studio automatically finds service(s) from current project for you. You can change the default service namespace in the "Namespace" text box to be more comfortable for you. Click "OK" and it's done.

Please note: if change and/or rebuilt your web service you have to update the web service reference in your Silverlight application. To update a web service reference you have to right click on its name in the Solution Explorer under Service References and select "Update Service Reference" from the offered content menu.

When you add or update a web service reference, Visual Studio, creates some files in Service References folder and ServiceReferences.ClientConfig file in the root of your Silverlight application.

Start consuming the web service

Security

All data sent from web service are sent as clear text. So, if you're sending sensitive data consider using appropriate encryption for your data.

Adding Service Reference

If you'd like to use your WCF Service in your Silverlight application you need to add a Service Reference.
In Visual Studio, in Solution Explorer right click on your Silverlight application folder and select "Add Service Reference" from the context menu. The pop-up appears.
To the Address field enter the WCF service's URL address. If you're adding an "project included" WCF service (your service is in your current solution) you can click to "Discover" button - it will list all found services in the current solution. Choose one you'd like to add.
Change the Namespace field if you'd like to.
Click "OK". If everything went smoothly your WCF service reference is successfully added and you can find the ServiceReferences.ClientConfig file in the application root.

Consuming web service

After you've created the Service Reference you're ready to use/consume the web service in your Silverlight application.
It's useful to import the Service Namespace to your application (Performance tip: every "dot" in your command requires a call to the object and it's dramatically impact on performance.)
And finally you can write "consumer" script.

Example: Suppose, you've created the Web Service. Next step is to add a Service Reference, setup Service Namespace as wcfService. Your Silverlight project's name is SilverlightApplication. First of all, open or create a xaml file which is about to consume your Web Service, import Service Namespace and write "consumer" script (in this example I'll call the Service after page is loaded). Because Service is asynchronious you need to add a Handler to sub what will consume the result from the Web Service. The MainForm.xaml contains <TextBlock x:Name="txtUsers"/>

Imports SilverlightApplication.wcfService

Partial Public Class MainPage
Inherits UserControl

Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As _
System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim client As New ServiceClient
With client
AddHandler .getUsersCompleted, AddressOf usersComplete
.getUsersAsync()
.CloseAsync()
End With
client = Nothing
End Sub

Private Sub usersComplete(ByVal sender As Object, ByVal e As _
getUsersCompletedEventArgs)
Dim users As New System.Text.StringBuilder
For Each u As usr In e.Result
With users
.Append("uID = " & u.uId.ToString & vbCrLf)
.Append("firstName = " & u.firstName & vbCrLf)
.Appned("lastName = " & u.lastName & vbCrLf)
End With
Next
txtUsers.Text = users.ToString
End Sub

That's all the basic information you need to know about Silverlight ∧ Web Service. For more details see next postings.

Happy coding!

No comments: