We are now going to have a look at how you can build and call a Web Service. We will display the returned data in a TextBlock when the user clicks a button. We will use a Silverlight-enabled WCF Service as the Web Service.
The Silverlight application before the user clicks the button
The Silverlight application after the user has clicked the button
Creating the Silverlight application
Let's start by creating a new Silverlight application that will host our control.
-
Open Visual Studio 8 and create a new Silverlight project called WebService.
-
Make sure that the Add a new ASP.NET Web project to the solution to host Silverlight option is selected. Make sure the Project Type dropdown is set to ASP.NET Web Application Project, then click OK.
Two projects will be added to the solution. The WebService project is the Silverlight application project and the WebService.Web project is the ASP.NET application hosting the Silverlight application. The WebService.Web project contains one .aspx and one .html page, which one you choose to use as the container is up to you; in this example however we will use the WebServiceTestPage.aspx page, so make sure it is set as the start page.
The page.axml page is the main page in the Silverlight application, and it should contain the basic framework for hosting Silverlight controls. We will later use this page to test our Web Service.
Adding the WCF Service to the Silverlight application.
The first step in creating a Web Service is to add the Silverlight-enabled WCF Service to the WebService.Web project.
-
Right click on the WebService.Web project name and select Add-New Item.
-
Select Silverlight-enabled WCF Service in the Add-New Item dialog box.
-
Name the Web Service wsData in the Name field and click Add.
This will add the required references and the two Web Service files; wsData.svc and wsData.svc.cs.
wsData.svc doesn't contain any code; it contains one line of mark-up code that tells ASP.NET where to find the code behind file for the Web Service.
wsData.svc.cs is the code behind file for the Web Service; here you write the logic.
Adding a test method to the Web Service
We are now going to add a method that we can call from the client. Start by opening the wsData.svc.cs file. Notice the two attributes on the wsData class. The ServiceContract attribute states that you intend to add methods to the class that remote callers can call access as part of a service. The AspNetCompatibilityRequirements attribute indicate that the class will have access to ASP.NET platform features such as session state, file authorization and url authorization similar to an ASMX service.
Each Web Service method needs to be decorated with the OperationContract attribute when adding it to the WCF class.
Let's add a method called GetText that returns a string value to test the service. Start by deleting the default DoWork method.
[OperationContract]
public string GetText()
{
return "The returned text.";
}
Build the solution by pressing Ctrl+B on the keyboard.
Testing the WCF Service
Let's try to call the GetText method from the Silverlight application. Open the Page.xaml page in the WebService project and add a button and a TextBlock control. When the user clicks the button the text returned from the Web Service method will be displayed in the TextBlock control. Add the following xaml code to the Page.xaml page.
<StackPanel>
<Button Content="Call WebService" Width="120" Height="30"
Margin="5" Click="Button_Click"></Button>
<TextBlock Name="lblResult" HorizontalAlignment="Center"
Margin="5">The result will be displayed here.</TextBlock>
</StackPanel>
Now let's add some logic to call the Web Service. Right click on the Button_Click event name in the Button tag and select Navigate to Event Handler, this takes us to the code behind page of the Page.xaml page and the corresponding event method.
In the Button_Click event we need to add code to call the method asynchronously, all Web Methods need to be called asynchronously.
Add a reference to the Web Service
The first thing we need to do is to add a reference to the Web Service.
-
Right click on the References folder in the WebService project.
-
Select Add Service Reference in the context menu.
-
Click on the Discover button. This searches the solution for available services. Alternatively you can write the address to the service in the Address field.
-
Select the wsData service in the list of services.
-
Name the namespace DataService in the Namespace field.
-
Click on the OK button to crate the necessary proxy classes for the Web Service.
A proxy to the service should appear under the Service References folder in the Solution Explorer. Click on the Show All Files button in the Solution Explorer to see all the files added to the proxy. There will also be a ServiceReferences.ClientConfig file added to the project root folder. This file configures the connection to the Web Service.
Writing the Web Service code
Now that we have a proxy to the Web Service we can begin to write the logic to handle the calls to the Web Service methods. The first thing we need to do is to add a couple of using statement to the Page.xaml.cs page. The following using statements are needed:
DataService: Makes it easier to access the Web Service classes.
System.Windows.Browser: To gain access to the HtmlPage class needed to get the current port.
System.ServiceModel: To gain access to the EndpointAddress and the BasicHttpBinding classes needed when creating the Web Service proxy object in code. We will override the settings in the ServiceReferences.ClientConfig file. We need to do that to prevent the Web Service from stop working when the port changes.
using WebService.DataService;
using System.Windows.Browser;
using System.ServiceModel;
Code in the Button_Click event
Next we will create an EndpointAddress object to define where the Web Service is located. We do this to ensure that we can call the service even if the port changes. You could change this endpoint address and base the URL on the current Silverlight page so that it will work wherever you deploy it.
private void Button_Click(object sender, RoutedEventArgs e)
{
System.ServiceModel.EndpointAddress endpoint = new
EndpointAddress("http://localhost:" +
HtmlPage.Document.DocumentUri.Port + "/wsData.svc");
}
Next we need to create a proxy object that will handle the call to the service. On the proxy object we will create an event handler for the GetTextCompleted event that will fire when the call returns from the service method call. It is named after the GetText method we created earlier in the Web Service class.
The default time out is 60 seconds, which might be a tad long, so we will change that to 30 seconds using the OperationTimeout property of the proxy object.
All calls to Web Services need to be done asynchronously so we will call the GetTextAsync method on the proxy object. When calling a method asynchronously we need to have a callback method present, in our case it is the GetTextCompleted method.
private void Button_Click(object sender, RoutedEventArgs e)
{
System.ServiceModel.EndpointAddress endpoint = new
EndpointAddress("http://localhost:" +
HtmlPage.Document.DocumentUri.Port + "/wsData.svc");
wsDataClient proxy = new wsDataClient(new BasicHttpBinding(), endpoint);
proxy.GetTextCompleted += new
EventHandler<GetTextCompletedEventArgs>(proxy_GetTextCompleted);
proxy.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(30);
proxy.GetTextAsync();
}
Callback method code
The last thing we need to do is to write the code in the callback method. Let's place the result in the TextBlock called lblResult we added to the Page.xaml page.
void proxy_GetTextCompleted(object sender, GetTextCompletedEventArgs e)
{
try { lblResult.Text = e.Result.ToString(); }
catch { lblResult.Text = "Error calling Web Service"; }
}
Press F5 on the keyboard to run the application and test the Web Service.