App Hub

Visuals & Media

Make your applications visually appealing with images, animations, and media.

Sensors & Other Phone Specific Features

Use unique features of the phone, such the accelerometer, GPS, and camera, in your applications.

Accessing a REST Web Service
Silverlight quickstart for Windows Phone development

Representational State Transfer (REST) refers to an architectural style for exposing resources on the web for access by clients. Many resources, such as blogs, maps, and products, are exposed as REST services on the web. Silverlight provides classes that make it easy to call REST services from a Windows Phone application. This QuickStart introduces how to call and work with REST services.

This QuickStart contains the following sections:

Note

The live samples in this QuickStart use Silverlight running in the browser to simulate the behavior in Silverlight for Windows Phone. The actual behavior may be slightly different in the Windows Phone emulator or on a Windows Phone device.

Calling REST Services

You call a REST service by using standard HTTP verbs (GET, POST, PUT, and DELETE). Resources are identified by a URI. A response contains a representation, typically XML or JavaScript Object Notation (JSON), of the specified resource. Requests are stateless, which means that all the information needed to complete a request must be included with each request.

One important aspect of calling a REST service is ensuring that you use the correct URI for the resource you' trying to access. Companies typically list the request requirements, including request parameters and the values that you should pass for the parameters. For example, to call the Bing Web services, you can review the Bing API guidelines.

Silverlight for Windows Phone provides several classes to call REST services. It's important to remember, however, that Windows Phone supports Silverlight 3, which means Silverlight 4 networking features aren't available to Windows Phone clients. For more information about the differences in networking capability between Silverlight for Windows Phone and Silverlight for the desktop, see Networking in Silverlight for Windows Phone.

To call a REST service from a Windows Phone client application, you can use either the WebClient or HttpWebRequest/HttpWebResponse classes. With either option, the requests are asynchronous. However, WebClient is the simpler of the two choices.

WebClient uses a simple event-based system to make requests and retrieve responses. To use WebClient, you call the appropriate Async method and handle the corresponding Completed event. The following table lists some of the WebClient methods and events that you should use, depending on the action and data type.

Action Data Type Methods and Events
GET String DownloadStringAsync method
DownloadStringCompleted event
GET Stream OpenReadAsync method
OpenReadCompleted event
POST String UploadStringAsync method
UploadStringCompleted event
POST Stream OpenWriteAsync method
OpenWriteCompleted event

The HttpWebRequest class enables you to have more control over the request message, such as sending HTTP PUT and DELETE messages. For more information about using the HttpWebRequest/HttpWebResponse classes, see the HttpWebRequest class overview.

Calling a REST Service Example

The following live example demonstrates how to use the WebClient class to send a request from a phone application to the Bing search service. In this example, you can change the selected search term by using the combo box, which updates the search URI. When you click the Search! button, a request is sent to the Bing search service. In addition to the search term, the request URI specifies that the results are a Web search and that the response is in XML. The results are parsed and displayed in the list box.

Note

Although the live example includes a Bing Application ID in the URI to complete the search request, the actual Application ID isn't shown in the code. To obtain an Application ID to call the Bing search service, see Getting Started with Bing Api Version 2.

Security Note

When connecting to a web service that requires an application key, don't store the application key with an application that will be run on a device. Instead, you can create a proxy web service to authenticate a user and call an external cloud service with the application key. For more information about security recommendations, see Web Service Security for Windows Phone.

The following shows the markup and code for this example.

XAML

<phone:PhoneApplicationPage
x:Class="WindowsPhoneApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="False">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem" >
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="LightGray"/>
</Style>
<Style x:Key="ComboBoxStyle" TargetType="ComboBox" >
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Gray"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="REST CLIENT"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="bing search"
Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
Height="99" Width="453" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="12,139,12,0" Grid.RowSpan="2">
<Button Content="Search!" Height="89" HorizontalAlignment="Left"
Margin="264,140,0,0" Name="button1"
VerticalAlignment="Top" Width="189" Click="button1_Click" />
<ComboBox Height="50" Style="{StaticResource ComboBoxStyle}"
HorizontalAlignment="Left" Margin="6,159" Name="comboBox1"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
VerticalAlignment="Top" Width="235" ItemsSource="{Binding}"
SelectionChanged="comboBox1_SelectionChanged" />
<TextBlock Height="36" HorizontalAlignment="Left" Margin="12,120"
Name="textBlock2" Text="Search Topic:" VerticalAlignment="Top" Width="121" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,1,0,0"
Name="textBlock3"
Text="URI:" VerticalAlignment="Top" />
<TextBlock Height="86" HorizontalAlignment="Left" Margin="6,28"
Name="uriTextBlock" TextWrapping="Wrap" Text="{Binding}"
VerticalAlignment="Top" Width="447" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,242,0,0"
Name="textBlock5"
Text="Results:" VerticalAlignment="Top" />
<ListBox Height="352" HorizontalAlignment="Left" Margin="6,271,0,0" Name="listBox1"
VerticalAlignment="Top" Width="444" ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{StaticResource PhoneForegroundBrush}" Width="418" BorderThickness="2"
Margin="2">
<StackPanel>
<TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap" />
<TextBlock Text="{Binding Path=Url}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>

C#

using System;
using System.Collections.Generic;
using System.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 Microsoft.Phone.Controls;
using System.Xml.Linq;
namespace WindowsPhoneApplication1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
String requestString =
"http://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";
string UriNoAppId =
"http://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";
public MainPage()
{
InitializeComponent();
List<string> searchTopics = new List<string>() { "Microsoft", "Silverlight", "Windows Phone" };
comboBox1.DataContext = searchTopics;
comboBox1.SelectedIndex = 0;
// Create the WebClient and associate a handler with the OpenReadCompleted event.
wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
}
// Call the topic service at the Bing search site.
WebClient wc;
private void CallToWebService()
{
// Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
wc.OpenReadAsync(new Uri(String.Format(requestString, comboBox1.SelectedItem.ToString())));
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
XElement resultXml;
// You should always check to see if an error occurred. In this case, the application
// simply returns.
if (e.Error != null)
{
return;
}
else
{
XNamespace web = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web";
try
{
resultXml = XElement.Load(e.Result);
// Search for the WebResult node and create a SearchResults object for each one.
var searchResults =
from result in resultXml.Descendants(web + "WebResult")
select new SearchResult
{
// Get the Title, Description and Url values.
Title = result.Element(web + "Title").Value,
Description = result.Element(web + "Description").Value,
Url = result.Element(web + "Url").Value
};
// Set the data context for the listbox to the results.
listBox1.DataContext = searchResults;
}
catch (System.Xml.XmlException ex)
{
textBlock2.Text = ex.Message;
}
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
CallToWebService();
}
// Update the textblock as the combo box selection changes.
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
uriTextBlock.DataContext = string.Format(UriNoAppId, e.AddedItems[0]);
}
}
// Simple class to hold the search results.
public class SearchResult
{
public string Title { get; set; }
public string Url { get; set; }
public string Description { get; set; }
}
}

Visual Basic

Imports System.Collections.Generic
Imports System.Linq
Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports Microsoft.Phone.Controls
Imports System.Xml.Linq
Namespace WindowsPhoneApplication1
Public Partial Class MainPage
Inherits PhoneApplicationPage
' Constructor
Private requestString As [String] = "http://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
Private UriNoAppId As String = "http://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
Public Sub New()
InitializeComponent()
Dim searchTopics As New List(Of String)() From { _
"Microsoft", _
"Silverlight", _
"Windows Phone" _
}
comboBox1.DataContext = searchTopics
comboBox1.SelectedIndex = 0
' Create the WebClient and associate a handler with the OpenReadCompleted event.
wc = New WebClient()
AddHandler wc.OpenReadCompleted, New OpenReadCompletedEventHandler(AddressOf wc_OpenReadCompleted)
End Sub
' Call the topic service at the Bing search site.
Private wc As WebClient
Private Sub CallToWebService()
' Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
wc.OpenReadAsync(New Uri([String].Format(requestString, comboBox1.SelectedItem.ToString())))
End Sub
Private Sub wc_OpenReadCompleted(sender As Object, e As OpenReadCompletedEventArgs)
Dim resultXml As XElement
' You should always check to see if an error occurred. In this case, the application
' simply returns.
If e.[Error] IsNot Nothing Then
Return
Else
Dim web As XNamespace = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web"
Try
resultXml = XElement.Load(e.Result)
' Search for the WebResult node and create a SearchResults object for each one.
' Get the Title, Description and Url values.
Dim searchResults = From result In resultXml.Descendants(web & "WebResult")New SearchResult() With { _
Key .Title = result.Element(web & "Title").Value, _
Key .Description = result.Element(web & "Description").Value, _
Key .Url = result.Element(web & "Url").Value _
}
' Set the data context for the listbox to the results.
listBox1.DataContext = searchResults
Catch ex As System.Xml.XmlException
textBlock2.Text = ex.Message
End Try
End If
End Sub
Private Sub button1_Click(sender As Object, e As RoutedEventArgs)
CallToWebService()
End Sub
' Update the textblock as the combo box selection changes.
Private Sub comboBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
uriTextBlock.DataContext = String.Format(UriNoAppId, e.AddedItems(0))
End Sub
End Class
' Simple class to hold the search results.
Public Class SearchResult
Public Property Title() As String
Get
Return m_Title
End Get
Set
m_Title = Value
End Set
End Property
Private m_Title As String
Public Property Url() As String
Get
Return m_Url
End Get
Set
m_Url = Value
End Set
End Property
Private m_Url As String
Public Property Description() As String
Get
Return m_Description
End Get
Set
m_Description = Value
End Set
End Property
Private m_Description As String
End Class
End Namespace

Detecting Networking Availability

To ensure a good user experience, you should verify that the phone has access to the Internet before calling a web service. You use the NetworkInterface.GetIsNetworkAvailable method to determine whether the phone has Internet connectivity. You can call this method before calling the web service. If the method returns false, either prompt the user to connect to a viable network, or let the user know that the web service call can't be completed. For an example of how to use this method, see the NetworkInterface.GetIsNetworkAvailable reference topic.

Note

The NetworkInterface.GetIsNetworkAvailable method call may return true on the emulator even when a network isn't available, so you should test your code on a device.

See Also

var gDomain='m.webtrends.com'; var gDcsId='dcschd84w10000w4lw9hcqmsz_8n3x'; var gTrackEvents=1; var gFpc='WT_FPC'; /*<\/scr"+"ipt>");} /*]]>*/
DCSIMG