wp7 hub_consuming data services
DESCRIPTION
Fase 3.4TRANSCRIPT
Consuming Data Services
CONNECTING TO A DATA SERVICE
Topics Windows Phone applications on a network The role of the Windows Phone emulator Creating network connections Using asynchronous network requests
Windows Phone on a network The Windows Phone device is very well connected
WIFI 3G GPRS
All these networks are accessed by programs that use the TCP/IP networking protocol
Your program does not have to worry about the underlying communication technology
4
Phone limitations A mobile phone does not have a working
connection at all times Mobile applications that use the network must
either “fail gracefully” or provide offline modes for their users
Any network request must provide progress information and use timeouts to ensure that a failed network doesn’t cause them to get stuck
5
Windows Phone networking Windows Phone Silverlight applications and XNA
games can use the network But they are not allowed to make “socket” based
connections in Version 1.0 of the operating system
All network requests must be calls to services that will deliver a result asynchronously
The network calls are exactly the same as those provided in the desktop .NET libraries
6
Asynchronous connections A program will never make a call to the network
and then wait for the result This is called synchronous operation, and is not
supported by any network calls on the phone Instead a program will make a call to the network to
initiate an operation The network object will then call back later with the
result of the operation
7
Asynchronous operation This form of event based operation is exactly the
same as the model used by Silverlight to accept user input
Silverlight elements can generate program events Button pressed, Text Changed etc
A program can bind to these events so that a method is called when an event occurs
8
Downloading Web Pages To get started we could look at
an application to “scrape” text off a web page
This can be used to obtain data for display
We can also use it to read structured data from the web, of which more later
9
The WebClient class
To start we need something that will do the work for us
The .NET WebClient class can be used to fetch information from the internet An instance of the WebClient class represents a
single web request We can use it to read HTML from a given web page
10
WebClient client;
Creating a WebClient
We can create a WebClient instance in the constructor for our page
11
// Constructor
public MainPage()
{
InitializeComponent();
client = new WebClient();
client.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(
client_DownloadStringCompleted);
}
Binding to the loaded event
This statement binds a method to the completed event
The method runs after the page is fetched
12
// Constructor
public MainPage()
{
InitializeComponent();
client = new WebClient();
client.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(
client_DownloadStringCompleted);
}
Displaying the result
The
client_DownloadStringCompleted method runs when the page text has arrived
It checks for an error and displays the text if there was none
13
void client_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
pageTextBlock.Text = e.Result;
}
}
Sending the request
This is the event handler for the button that is pressed to start the transaction
It calls the DownloadStringAsync method
on the WebClient to start the download It is given a Uri to download from
14
private void loadButton_Click(object sender,
RoutedEventArgs e)
{
client.DownloadStringAsync(new Uri(urlTextBox.Text));
}
The Uri
A Uri instance gives the address of a resource It can be created from a string of text In this program the Uri is created from a TextBox on
the user interface
15
private void loadButton_Click(object sender,
RoutedEventArgs e)
{
client.DownloadStringAsync(new Uri(urlTextBox.Text));
}
16
Demo 1: Web Scraping
Demo
Review Windows phones can make connections to services
over the network All network requests are asynchronous
The result of a network request is delivered by an event generated in the client
The WebClient class provides a very easy way of loading the content of urls
17
USING LINQ TO READ STRUCTURED
Topics Structured data and LINQ Databases and objects Database queries and LINQ Creating Silverlight layout templates Databinding to lists Using LINQ queries to produce object collections
Reading Twitter XML feeds We can use a WebClient request
to read structured data from a web host
The Twitter feed information can be supplied as an XML structured data file
Our program must pull out some content and display it
20
Reading the Twitter feed
This code will fetch the XML that describes a Twitter feed
The URL contains the Twitter username
21
private void loadButton_Click(object sender, RoutedEventArgs e)
{
string url = "http://twitter.com/statuses/user_timeline/" +
nameTextBox.Text + ".xml";
client.DownloadStringAsync(new Uri(url));
}
XML structured data We have already seen XML in the markup language
used by Silverlight to describe pages The XML for a Twitter feed contains elements and
properties which are formatted to describe Twitter post information
We could write some C# to decode the feed, but we are going to use LINQ instead
LINQ stands for Language Integrated Query
22
LINQ LINQ is a technology that is part of the .NET system
libraries It builds on C# language features to provide easy
data transfer between structured data storage and the object models used by modern languages
It is well worth knowing about
23
A diversion into databases If you want to store large amounts of structured
data you will not write a system to do this Instead you will use a database The database manages the data for you, and your
program will send commands to it to add, remove and search for data
24
A simple Database
We can start by considering a simple sales database
This is the customer table Each row describes a single customer
25
Name Address Bank Details Customer ID
Rob 18 Pussycat MewsNut East Bank 123456
Jim 10 Motor Drive Big Fall Bank 654322
Ethel 4 Funny Address Strange bank 111111
Two other tables
Sales table
26
Customer ID Product ID Order Date Status
123456 1001 21/10/2010 Shipped
111111 1002 10/10/2010 Shipped
654322 1003 01/09/2010 On order
Product ID Product Name Supplier Price
1001 Windows Phone 7 Microsoft 200
1002 Cheese grater
Cheese Industries 2
1003 Boat hook John’s Dockyard 20
Product Table
Using the database
27
We can combine the information in the tables to obtain transaction details Rob has Customer ID 123456 Customer ID 123456 ordered product ID1001 1001 is the product ID of a Windows Phone
Rob bought a Windows Phone We get the database to do this for us by issuing
queries to it
Database queries
This SQL query will create a table that contains all the orders placed by Rob
This result can then be used as the basis of another query
Database queries are much easier to create than the equivalent program statements to work through the data
28
SELECT * FROM Orders WHERE CustomerID = "123456"
A C# sales database
If we wrote a C# program to store the sales database our starting point would be class designs
The above class holds Customer information
29
public class Customer
{
public string Name {get; set;}
public string Address { get; set; }
string BankDetails { get; set; }
public int ID { get; set; }
}
Holding multiple Customers
Once we have a class that contains the required data we can create collections of that object
Above we have created a list of customers We can then store customers in the list by adding
them to it
30
List<Customer> Customers = new List<Customer>();
Searching for customers
This is the C# code that implements the SQL query we saw earlier
31
public List<Order> FindCustomerOrders(int CustomerID)
{
List<Order> result = new List<Order>();
foreach ( Order order in Orders )
{
if (order.CustomerID == CustomerID)
{
result.Add(order);
}
}
return result;
}
Databases and objects If object-oriented programs and databases are to
work together we need something to convert from database tables to objects and back
We can do this by creating of “glue” code that creates objects and stores them back in tables
However, this task is made much easier by LINQ
32
A LINQ query
This is the LINQ code that implements the SQL query we saw earlier
It does not look like legal program statements, but it compiles perfectly
It is worth a closer look
33
var orderQueryResult =
from order in db.Orders
where order.CustomerID == "123456"
select order;
Query result
The query returns a result which is given the type var var means “a type which works here” The type of a var variable depends on the
context of the declaration In this case orderQueryResult will hold a collection
of var objects that look like orders
34
var orderQueryResult =
from order in db.Orders
where order.CustomerID == "123456"
select order;
Iteration source
This sets up the iteration through the elements in a table
The db variable represents the database connection and we are using the Orders table from that database
35
var orderQueryResult =
from order in db.Orders
where order.CustomerID == "123456"
select order;
Restriction operation
This is the restriction operation that identifies the orders to be selected from the table
In this case we are looking for orders with the CustomerID of 123456
36
var orderQueryResult =
from order in db.Orders
where order.CustomerID == "123456"
select order;
Selection operation
This identifies the item to be selected and added to the result when the restriction operation succeeds
This means that we will get a collection of var results that look like order objects
We can then use these objects in our program
37
var orderQueryResult =
from order in db.Orders
where order.CustomerID == "123456"
select order;
Databases on Windows Phone LINQ is a great way to combine object oriented
code and databases Unfortunately the present version of Windows
Phone does not have database support But it does contain the LINQ libraries This would seem a strange design choice Fortunately LINQ can also be used to read
structured data and create objects from it
38
Twitter XML
This is an abridged Twitter status XML file
39
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<created_at>Tue Oct 12 11:57:37 +0000 2010</created_at>
<text> Hello from Twitter.</text>
<user>
<id>2479801</id>
<name>Rob Miles</name>
<profile_background_image_url>
http://s.twimg.com/a/1286/images/themes/theme1/bg.png
</profile_background_image_url>
</user>
</status>
</statuses>
Performing the query
The first thing we need to do is get LINQ to create a LINQ XML element or XElement
We will be able to perform LINQ operations on the XElement value as if it was a database source
The Parse method works through the XML data string returned by the server
40
XElement TwitterElement = XElement.Parse(twitterText);
Creating the display objects We now have an easy way that we can use LINQ to
pull the required data out of the XML feed We want to obtain and display
The text of the Twitter post The data of the post The image of the Twitter user
Once we have these values we need to display them
41
Creating a display class
This the class that we will actually use to display a post on the screen
We will use Silverlight data binding to connect these properties to display elements
42
public class TwitterPost
{
public string PostText { get; set; }
public string DatePosted { get; set; }
public string UserImage { get; set; }
}
Using LINQ to create the display
This is the LINQ query that will work through the status elements in the XML and create new TwitterPost instances from each status entry
43
var postList =
from tweet in twitterElements.Descendants("status")
select new TwitterPost
{
UserImage = tweet.Element("user").
Element("profile_image_url").Value,
PostText = tweet.Element("text").Value,
DatePosted = tweet.Element("created_at").Value
};
Using LINQ to create the display
There is no restriction part as we want all the status elements
We could add one if we wanted to select particular ones based on a criteria
44
var postList =
from tweet in twitterElements.Descendants("status")
select new TwitterPost
{
UserImage = tweet.Element("user").
Element("profile_image_url").Value,
PostText = tweet.Element("text").Value,
DatePosted = tweet.Element("created_at").Value
};
Finding XML elements
The Element method locates an element with a particular name
It can be used on the element it returns This is how we get the profile image
45
var postList =
from tweet in twitterElements.Descendants("status")
select new TwitterPost
{
UserImage = tweet.Element("user").
Element("profile_image_url").Value,
PostText = tweet.Element("text").Value,
DatePosted = tweet.Element("created_at").Value
};
The postList variable The postList variable is a var type
This means that it will be set to the result of an operation that will build the type when it is used
In fact postList refers to a list of TwitterPost values
Now we need to get that list onto the Phone display
46
XAML templates What we really want to do is bind our list of Twitter
posts to some kind of list on the phone It turns out that this is very easy to do We can create a list template that describes the
layout of some Silverlight elements that can be bound to properties in the TwitterPost class
47
What the display will look like
I want each twitter post to look like this A picture on the left hand side, with the post
date and content arranged to the right of this
We can use the Silverlight StackPanel element to lay this out for us
48
Outer StackPanel
The outer stack panel lays out elements across the list element
49
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
Horizontal Stack Panel
There are two elements in the horizontal stack panel One is the image of the Twitter user The other will contain the date and the post text
50
User Image
This is the image of the Twitter user The source property gives the url of the image to be
displayed
51
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
Post details
The second element is another Stack Panel This contains the post date above the post text
52
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
Post details
This is the date posted element It binds to the DatePosted property in a TwitterPost
value
53
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
Post text
This is the post text itself This is set to wrap around the text area
54
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
StackPanel A StackPanel will automatically arrange the items
that are placed within it We have seen that we can place one StackPanel
value inside another They allow you to create layouts that position
themselves automatically
55
<ListBox Height="442" HorizontalAlignment="Left"
Name="tweetsListBox" VerticalAlignment="Top" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The Complete ListBox template
56
<ListBox Height="442" HorizontalAlignment="Left"
Name="tweetsListBox" VerticalAlignment="Top" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A ListBox display template
57
The ListBox is called tweetsListbox
<ListBox Height="442" HorizontalAlignment="Left"
Name="tweetsListBox" VerticalAlignment="Top" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A ListBox display template
58
It contains an item template for each list item the box is going to display
<ListBox Height="442" HorizontalAlignment="Left"
Name="tweetsListBox" VerticalAlignment="Top" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" />
<StackPanel Width="370">
<TextBlock Text="{Binding DatePosted}"
Foreground="#FFC8AB14" FontSize="22" />
<TextBlock Text="{Binding PostText}"
TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A ListBox display template
59
This is the StackPanel we created earlier
Putting it all together Now we have a ListBox template for the dislay that
will lay out the tweets the way that we want them to appear
The next thing is to connect the ListBox to a datasource that contains a collection of TwitterPost objects for display
First we can take a look at how such a list could be made
60
TwitterPost p1 = new TwitterPost
{
DatePosted = "Tue Oct 12 11:57:37 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is a test post from Rob"
};
TwitterPost p2 = new TwitterPost
{
DatePosted = "Wed Oct 13 14:21:04 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is another test post from Rob"
};
List<TwitterPost> posts = new List<TwitterPost>();
posts.Add(p1);
posts.Add(p2);
Displaying Lists of Tweets
61
TwitterPost p1 = new TwitterPost
{
DatePosted = "Tue Oct 12 11:57:37 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is a test post from Rob"
};
TwitterPost p2 = new TwitterPost
{
DatePosted = "Wed Oct 13 14:21:04 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is another test post from Rob"
};
List<TwitterPost> posts = new List<TwitterPost>();
posts.Add(p1);
posts.Add(p2);
Displaying Lists of Tweets
62
This code creates two TwitterPost instances
TwitterPost p1 = new TwitterPost
{
DatePosted = "Tue Oct 12 11:57:37 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is a test post from Rob"
};
TwitterPost p2 = new TwitterPost
{
DatePosted = "Wed Oct 13 14:21:04 +0000 2010",
UserImage = http://a3.twimg.com/1501/me2_normal.jpg",
PostText = "This is another test post from Rob"
};
List<TwitterPost> posts = new List<TwitterPost>();
posts.Add(p1);
posts.Add(p2);
Displaying Lists of Tweets
63
These are then added to a list of posts
Binding an XML data source
This sets the ItemSource property of the tweetsListBox to the collection of posts that we just created
Data binding will do the rest for us
64
tweetsListBox.ItemsSource = posts;
Binding to the twitter data
To see the posts loaded from the Twitter feed we use the list created by the LINQ query
The list will expand to fill the display and provide scrolling support if you want to view the rest of the items
65
tweetsListBox.ItemsSource = postList;
66
Demo 1: Twitter viewer
Demo
Review Web requests can return structured data in XML
format The Language Integrated Query (LINQ) tools
provide a way of converting structured data into objects
LINQ can decode an XML document and create objects with data properties
Collections of objects can be bound to Silverlight lists which contain display templates
67
USING NETWORK SERVICES
Topics Creating a network service Proxy objects and services Service contracts and interfaces Creating a client Adding a service reference to a project Connecting to a service
Creating services Up until now all our applications have consumed
services provided by other people Now we are going to learn how to create services of
our own and consume them on the Windows Phone We are going to use the Windows Communications
Framework (WCF) to do this
70
Services and proxies
The service infrastructure hides the nature of the network connection from both the server and the client The server contains methods that are called to
provide the service The client calls methods on a proxy object that
represents the service
71
Server
Service Proxy Object
Creating a Service
A service is a Visual Studio project like any other It can run in a test environment on the
development machine
72
The “Joke of the day” service
The “Joke of the day” service contains a single method that accepts an integer and returns a string containing a joke of that “strength”
73
[ServiceContract]
public interface IJokeOfTheDayService
{
[OperationContract]
string GetJoke(int jokeStrength);
}
Contract attributes
The [ServiceContract] and
[OperationContract] attributes are used by the build process to generate the service descriptions
74
[ServiceContract]
public interface IJokeOfTheDayService
{
[OperationContract]
string GetJoke(int jokeStrength);
}
The “Joke of the day” method
The [ServiceContract] and
[OperationContract] attributes are used by the build process to generate the service descriptions
75
public class JokeOfTheDayService : IJokeOfTheDayService
{
public string GetJoke(int jokeStrength)
{
string result = "Invalid strength";
switch (jokeStrength)
{
case 0: result = "Joke 0 text";
break;
case 1: result = "Joke 1 text";
break;
case 2: result = "Joke 2 text";
break;
}
return result;
}
}
Joke of the day service
We can test the service by issuing calls on the methods from the WCF Test Client
This runs as part of the service project
76
Joke of the day service description
The service also provides a service description that can be used to create clients that use it
77
Creating a Service Reference
A service reference is added alongside dll references that a project uses
It will be added to the Visual Studio project
We manage the service properties from Solution Explorer and the Properties Pane
78
Browsing for a service
We enter the address of the service and Visual Studio downloads the service description
79
Service reference management Once a service has been added it
appears in the project A given project can connect to
multiple services
80
Making a proxy object
The proxy object provides the link between the client application and the service providing the resource
81
JokeOfTheDayService.JokeOfTheDayServiceClient jokeService;
// Constructor
public MainPage()
{
InitializeComponent();
jokeService =
new JokeOfTheDayService.JokeOfTheDayServiceClient();
jokeService.GetJokeCompleted +=
new EventHandler<JokeOfTheDayService.
GetJokeCompletedEventArgs>
(jokeService_GetJokeCompleted);
}
Making a proxy object
The proxy object provides the link between the client application and the service providing the resource
82
JokeOfTheDayService.JokeOfTheDayServiceClient jokeService;
// Constructor
public MainPage()
{
InitializeComponent();
jokeService =
new JokeOfTheDayService.JokeOfTheDayServiceClient();
jokeService.GetJokeCompleted +=
new EventHandler<JokeOfTheDayService.
GetJokeCompletedEventArgs>
(jokeService_GetJokeCompleted);
}
Create the service
Making a proxy object
The proxy object provides the link between the client application and the service providing the resource
83
JokeOfTheDayService.JokeOfTheDayServiceClient jokeService;
// Constructor
public MainPage()
{
InitializeComponent();
jokeService =
new JokeOfTheDayService.JokeOfTheDayServiceClient();
jokeService.GetJokeCompleted +=
new EventHandler<JokeOfTheDayService.
GetJokeCompletedEventArgs>
(jokeService_GetJokeCompleted);
}
Bind to the service completed event
Asynchronous service calls Like every other network mechanism, requests to
web services are asynchronous The foreground program sends off the service
request When the service completes it fires an event in
the program We have to bind an event handler to the service
completed message This will display our joke
84
Displaying the result
This method checks the return arguments to make sure that the call has succeeded
If it has, the joke is displayed in a TextBox
85
void jokeService_GetJokeCompleted(object sender,
JokeOfTheDayService.GetJokeCompletedEventArgs e)
{
if (!e.Cancelled)
{
jokeTextBlock.Text = e.Result;
}
}
Sending the request
When the button is clicked it loads the requested strength and calls the method on the instance of the service
86
private void getJokeButton_Click(object sender,
RoutedEventArgs e)
{
int strength = 0;
if (int.TryParse(strengthTextBox.Text, out strength))
{
jokeService.GetJokeAsync(strength);
}
}
Errors and Timeouts
Network connections are not guaranteed It may be impossible to make a connection to
a service Your application should handle this
87
88
Demo 1: Joke Service
Demo
Review Windows Phone devices can act as clients to
servers running C# programs that provide services The network abstracts the client request into a
method call in a proxy object A service exposes a description that can be used by
Visual Studio to create appropriate proxy objects
89
EXERCISE 1: CREATE A WCF SERVER TO STORE DATA
EXERCISE 2: CREATE A WINDOWS PHONE CLIENT APPLICATION