WP7 HUB_Consuming Data Services

Preview:

DESCRIPTION

Fase 3.4

Citation preview

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