Anda di halaman 1dari 22

Networking In Silverlight

Overview
Developing Silverlight applications may not always be entirely intuitive to experienced
ASP.NET developers. A Silverlight application executes within a plug-in environment
and, as such, there are no automatic postbacks to a server that originate from a Silverlight
application. If a call to a server is necessary from a Silverlight application, the call must
be manually initiated by the developer.

Silverlight supports several networking protocols that enable communication with a


server as described in the sections below.

Sockets Programming
Silverlight supports sockets programming through the System.Net.Sockets namespace. A
socket is a low-level communication channel that is generally configured using TCP/IP.
Silverlight supports asynchronously sending data back and forth across a socket over
ports ranging from 4502 to 4534. Silverlight supports cross-domain socket
communications between a Silverlight application and any server, provided that a special
security policy file is in place on the server. (see footnote)

Sockets are most commonly used to push data from the server to a client. A socket, when
used in this manner, creates a client-server relationship based on the publisher-subscriber
paradigm. This eliminates the need to have the client periodically poll the server for
updates, which may (or may not) have occurred.

Service Oriented Architecture


Service Oriented Architecture (SOA) is an industry standard that defines how an object
should be created so that the methods of the object are accessible over the Web and can
be consumed by using well supported Web standards such as HTTP, XML, SOAP, and
WSDL.

Serialization

The Web is a stateless environment. In traditional web applications, communication


between the client and the server is almost always initiated by the client. The server
responds and from that point forward, messages continue to be sent back and forth
between the client and server to conduct the communications necessary to deliver the
application. The messages that are sent between the client and the server contain only

1
simple text. But then how do more complex items such as images, graphs, animations,
and multimedia get transported from a Web server to a client? Such items are first
converted to text, then transported over the Web, and then recreated from the text
representation.

The process of converting a complex item to a text representation is call serialization.

The process of converting an item from a serialized, text representation back to the
original object is called deserialization.

The most common formats for an item to be converted to for transportation over the Web
are XML, SOAP, and JSON. The .NET Framework and Silverlight both include facilities
for serializing and deserializing data.

Web Services

A common implementation of SOA is a Web service. Developers have been able to


create Web services by using the .NET Framework and ASP.NET since its originall
release.

Creating a Web Service to use with Silverlight

The general steps to build a Web service that can be consumed by a Silverlight
application are as follows:

1. When creating a new Silverlight project in Visual Studio, be sure to select the
option to add a new Web to the solution. The new Web project that is created
serves as a test harness project for the Silverlight application.
2. A Web service will not exist in the new Web by default but can easily be added
by right-clicking the Web project and selecting Add New Item. From the Add
New Item dialog, select Web Service (if you are supporting .NET 2.0 ASMX
Web Services), or Silverlight-Enabled WCF Service (if you are supporting .NET
3.5 on the target web server). Note that Silverlight 2 can use either ASMX or
WCF Web Services, but there are restrictions on what WCF functionality you can
use from Silverlight 2 because only the Basic HTTP Binding is supported.
3. The figure below illustrates the project as displayed in the Solution Explorer once
the new Silverlight project is created and a new ASMX Web service is added to
the project. The example illustrated here will become a Web service that will read
weather forecast data from a database.

2
3
The entity relationship diagram for the Forecast database that is used by the Web service
is shown in the figure below.

The example Web service returns a generic list of forecast objects. In order for a class to
be able to be serialized, transported over the Web, and then deserialized, the class must
contain a default constructor and must be marked up by using the [Serializable] attribute.

Once the Web service has been created and tested, add a Service Reference to the
Silverlight project so that the Silverlight project can consume the Web service. Complete
coding the control and integrate feedback from the Web service to complete the control.
Be aware that as of Silverlight, only asynchronous calls can be made to any type of
service. Hence, a small amount of additional coding and planning is required to
accommodate for the asynchronous processing. The resulting Silverlight control is shown
in the figure below.

4
Windows Communication Foundation

Windows Communication Foundation (WCF) is the latest distributed application


development technology from Microsoft. WCF consolidates Web services and .NET
remoting into a single technology. Creating a WCF service is similar to creating a Web
service; however, the programming steps more closely follow object-oriented (OO)
principles. Every WCF service class must implement an interface. An interface defines
the contract (guaranteed internal schema and design) to which a class must adhere when
the interface is implemented. If a developer knows that a class implements a particular
interface, the developer can rest assured that the class implements a particular internal
structure. When a WCF service is consumed by a Silverlight application using Visual
Studio 2008, Visual Studio creates a proxy class for communicating with the service. The
proxy class is created by discovering details about the service from a file that both a Web
service and a WCF service expose, the Web Service Description Language (WSDL) file.
A WSDL file is created using a standard XML grammar. (see footnote)

Beyond implementing an interface and custom types, the process of developing a WCF
service is almost identical to developing a Web service. The example service created
above can be replicated by using a WCF service with minimal differences.

5
Other Networking Protocols
Silverlight supports the use of other communication protocols for use in communicating
with and consuming services and Web resources.

Plain Old XML

Plain Old XML (POX), or simple, well-formed, and valid XML documents and XML
fragments can be programmatically sent and received over the Web to enable
communication with services. In most cases, passing data over the Web by using POX
will require more coding for the developer but offers the developer the ability to fully
customize the schema of the XML being sent. Additionally, there may be scenarios
where a service being consumed does not fully support all Web standards and XML must
be used to exchange data with the service.

JavaScript Object Notation

JavaScript Object Notation (JSON) is a succinct and simple-to-read communication


protocol, which minimizes the size of messages sent over the Web. It is most often used
in Ajax applications. The code snippets below illustrate various JSON data
configurations. Curly brackets denote objects and square brackets denote arrays.

// object with a single property


{"Name":"Shannon"}

// object with multiple properties


{"Name":"Shannon","Gender":"Male"}

// object with single property, which is an array


{
"Athletes",
[
"Name":"Shannon",
"Name":"Benny",
"Name":"Sean",
"Name":"Tom",
"Name":"Matt"
]
}

Representational State Transfer (REST)

Representational State Transfer (REST) is a method of transporting domain-specific data


over HTTP without also transporting additional metadata or a containing transport
protocol such as HTML or SOAP. Silverlight supports communicating with services
through REST.

6
HTTP is an acronym for Hypertext Transport Protocol and is the standard protocol used
to communicate over the Web. HTTP consists of request and response messages that are
transported over the Web between computers with one computer acting as a client and the
other computer acting as a server. HTTP messages are referred to as HTTP packets and
contain a head section and a body section. The head section of an HTTP packet contains
information that is used by the application that receives and processes the HTTP packet
while the body section contains the data that is being transported using HTTP such as an
HTML document. The contents of the body section is referred to as the "payload". The
contents of the payload may include an HTML or XML document and, in turn, typically
contains subsections of its own, such as contents to display on an HTML document or
scripts.

REST was designed by the same people that designed HTTP and it eliminates the extra
layer of transport protocol. The head section of an HTTP can contain commands and
instructions such as GET or POST that are read and executed by the application that
processes the packet. The commonly-used HTTP commands are GET, POST, PUT, and
DELETE. These commands are analogous to the SQL DML commands that are also
referred to as NURD (new, update, read, delete) or CRUD (create, read, update, delete).

The POST command is used to issue create, update, or delete commands. The GET
command is used to issue a read command. The PUT command is used to issue create or
overwrite commands. The DELETE command is used to issue a delete command.
Through the aforementioned commands, REST supports code on demand and it also
supports embedded hyperlinks.

Applications that communicate over the Web by using REST are referred to as
"RESTful" applications. REST also eliminates, or extremely reduces, the need to manage
state. The Web is, by nature, a stateless environment. When a server receives an HTTP
request, it fulfills the request and returns an HTTP response. Once the response is sent,
the server forgets about the request and moves on to the next request. The server's lack of
ability to remember who a client is between calls is referred to as stateless. The ability for
a server to remember clients between requests is referred to as managing state. In most
modern Web development technologies, servers manage state by using cookies. The
REST standard discourages the use of cookies due to security and navigation precautions.

The most commonly-used method of communicating between a client application and a


server over the Web is currently a Web service. Web services are designed based on a
remote procedure call (RPC) where client applications must have knowledge about a
service in order to be able to consume it (by using WSDL). REST contains embedded
hyperlinks and it can use hyperlinks to fully describe a service, thus eliminating the need
for additional discovery technologies, such as WSDL, and it can use hyperlinks to
manage state information.

Syndication Protocols

7
In addition to supporting standard communication protocols, Silverlight also supports the
two most commonly-used syndication protocols, RSS and ATOM.

Really Simple Syndication

Really Simple Syndication (RSS) is an XML grammar that is used to syndicate


frequently updated content sources such as blogs. An RSS document is referred to as an
RSS feed. RSS was originally created by Netscape in 1999 and has since gained
widespread popularity. An RSS document defines a collection of channel elements. Each
channel represents a particular publication channel such as a blog. Each channel element
contains a collection of items. Each item represents a particular publication entry such as
a blog entry.

RSS documents can be easily and automatically updated once created and, typically, have
a .rss file extension. Just as a Web browser reads and parses HTML documents, an RSS
feed reader, or news reader, reads and parses RSS documents. The primary benefit of
using RSS is that users can subscribe to an RSS feed to be notified when new content is
published. Several versions of RSS have been released but the current official version is
version 2.0. The markup listing below illustrates an RSS document:

Code Sample: NetworkingInSilverlight/Demos/pets.rss


<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>My Pet Blog</title>
<link>http://localhost/myPetBlog</link>
<description>I blog about my pets here for now</description>
<item>
<title>Ladybird Found</title>
<link>http://localhost/myPetBlog/Item1</link>
<description>Want to read about how we found LadyBird?</description>
</item>
<item>
<title>LadyBird Groomed</title>
<link>http://localhost/myPetBlog/Item2</link>
<description>We found a great groomer</description>
</item>
</channel>
</rss>
Code Explanation

• The root <rss> element contains a collection of channel <channel> elements with
each defining a separate RSS syndication source.
• Each channel must include the title of the channel, the link to the channel, and a
description of the channel.
• Each channel <channel> element contains a collection of <item> item elements
with each defining a single item to be published.

8
• Each item must include the title of the item, the link to the item, and a description
of the item.
• An RSS feed reader, also known as an aggregator, can read the document and
provide updated information with links to the user as the RSS document is
updated.

ATOM
A problem with RSS is that several different and incompatible versions exist. In an effort
to resolve the incompatibilities and inconsistencies between the various versions of RSS,
a new syndication standard named Atom was created. Atom is divided into two
technologies, the Atom Syndication Format and the Atom Publishing Protocol.

The Atom Syndication Format is a custom XML grammar that serves much the same
purpose as the RSS XML grammar. An Atom Syndication Format file is a XML file with
a .atom file extension. The markup listing below illustrates the Atom version of the pet
blog entry:

Code Sample: NetworkingInSilverlight/Demos/pets.atom


<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>My Pet Blog</title>
<subtitle>I blog about my pet here for now</subtitle>
<link href="http://localhost/myPetBlog"/>
<updated>2008-01-30T09:30:00Z</updated>
<author>
<name>Shannon Horn</name>
<email>shannonhorn@msn.com</email>
</author>
<entry>
<title>Ladybird Found</title>
<link href="http://localhost/myPetBlog/Item1"/>
<updated>2008-01-30T09:30:00Z</updated>
<summary>Want to read about how we found LadyBird?</summary>
</entry>
</feed>

Code Explanation

The Atom Publishing Protocol is a query language similar to the Structured Query
Language (SQL) designed for use with the Atom Syndication Format. The Atom
Publishing Protocol consists of four primary commands: GET, POST, PUT, and
DELETE, analagous to the SQL SELECT, INSERT, UPDATE and DELETE statements.

9
Windows Azure
Cloud Computing refers to internet-based resources are provided in a highly scalable
service. This can save companies money because they do not have to invest in expensive
hardware to provide high scalability. Also, maintenance and power costs can be greatly
reduced. The Azure Services Platform is Microsoft's Cloud Computing solution.

The Azure Services

Azure is comprised of the following components and services:

• Live Services: An API provided for developers to perform searching, social


networking, and other functionality provided by Microsoft's Live Website
(www.live.com).
• Microsoft SQL Services: provides database capabilities in the Cloud to store,
retrieve, and update relational data.
• Microsoft .NET Services: provides security, workflow, and integration
capabilities to cloud-based applications.
• Microsoft SharePoint Services and Dynamics CRM Services: this is a future
capability, allowing developers to extend their SharePoint and Dynamics
applications into the Cloud.

Live Search

Live Search (http://dev.live.com/livesearch/) allows you to add robust searching to your


website or application. You can also use Live Search to increase traffic to your website,
and even generate revenue with an ad-based monetization scheme.

To begin using Live Search, you must create an Application ID by visiting


http://search.live.com/developers/createapp.aspx. This Application ID allows you to set
references to the Live Search web services and execute calls against them. We'll look at a
full example of using Live Search in the Labs for this chapter.

Lab: Networking In Silverlight


In this lab, you will create the foundation for a fully functional Silverlight application.
You will create the underlying database and Web service that the application will use to
display data. The lab is modeled to follow real world development practices.

10
Exercise: Create the Athlete Database

Duration: 20 to 30 minutes.

In this exercise, you will create a new SQL Server 2005 database that contains at least
three tables that will store athlete information. The steps in the exercises in this lab will
guide you to build a simulated athlete management system using Silverlight. If you would
like, and you have adequate experience, feel free to modify and customize the lab steps to
your liking.

1. Start or open Visual Studio 2008.


2. Create a new Silverlight project using the programming language of your choice.
When prompted, select the option to add a new Web to the solution. The new
Web will serve as the test harness project for the Silverlight application and it will
contain any server-side components for the project. The Default.aspx page that is
automatically added to the new Web may be deleted, if desired.
3. Let's bring in a test database to the solution. Right-click the App_Data folder in
the Solution Explorer and select Add Existing Item. Browse to the completed
database located at
ClassFiles\NetworkingInSilverlight\Solutions\AthleteManagerNetworking\Athlet
eManager_Web\App_Data

Exercise: Create the Athlete Class

Duration: 5 to 10 minutes.

In this exercise, you will create a class that represents an athlete.

1. Add a new class to the Web project (not the Silverlight project).
2. Design the class to contain athlete. Mark up the class using the Serializable
attribute. The code for the example Athlete class is shown below.

using System;
/// <summary>
/// Summary description for Athlete
/// </summary>
[Serializable]
public class Athlete
{
#region Data members
// data members.
public int AthleteId { get; set; }
public int SportId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }

11
public string Phone { get; set; }
public string Email { get; set; }
public string Website { get; set; }
public string Photo { get; set; }
public int Height { get; set; }
public int Weight { get; set; }
public string Biography { get; set; }
public string Notes { get; set; }
#endregion

#region Constructors
public Athlete() { }

public Athlete(string firstName, string lastName)


{
this.FirstName = firstName;
this.LastName = lastName;
}

public Athlete(int sportId,string firstName, string lastName, string


address, string photo, string city, string state, string zip, string
phone, string email, string website, int height, int weight, string
biography, string notes)
{
this.SportId = sportId;
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
this.City = city;
this.State = state;
this.Zip = zip;
this.Phone = phone;
this.Email = email;
this.Photo = photo;
this.Website = website;
this.Height = height;
this.Weight = weight;
this.Biography = biography;
this.Notes = notes;
}
public Athlete(int athleteId, int sportId, string firstName, string
lastName, string address, string photo, string city, string state,
string zip, string phone, string email, string website, int height, int
weight, string biography, string notes)
{
this.AthleteId = athleteId;
this.SportId = sportId;
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
this.City = city;
this.State = state;
this.Zip = zip;
this.Phone = phone;
this.Email = email;
this.Website = website;
this.Photo = photo;

12
this.Height = height;
this.Weight = weight;
this.Biography = biography;
this.Notes = notes;
}
#endregion
}

Exercise: Create the Sport Class

Duration: 5 to 10 minutes.

In this exercise, you will create a class that represents a sport.

1. Add a new class to the Web project (not the Silverlight project).
2. Design the class to contain sport information. Mark up the class using the
Serializable attribute. The code for the example Sport class is shown below.

using System;

/// <summary>
/// Summary description for Sport
/// </summary>
[Serializable]
public class Sport
{
#region Data members
// data members.
public int SportId { get; set; }
public string Name { get; set; }
#endregion

#region Constructors
public Sport() { }

public Sport(string name)


{
this.Name = name;
}
#endregion
}

Exercise: Create the Athlete Service

Duration: 30 to 45 minutes.

In this exercise, you will create a Web service that uses the classes and database created
previously. This service will be used by the Silverlight application.

1. Add a new Web service (or WCF service, if desired) to the Web project (not the
Silverlight project).

13
2. Add methods to the Web service code file for CreateAthlete, CreateUser,
ReadAthletes, ReadAthleteById, ReadSports, and AuthenticateUser. The code for
the example AthleteService is shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Security;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;

/// <summary>
/// Summary description for AthleteService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET
AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class AthleteService : System.Web.Services.WebService
{

SqlConnection cn = new
SqlConnection(ConfigurationManager.ConnectionStrings["athleteDB"].Conne
ctionString);

public AthleteService()
{

//Uncomment the following line if using designed components


//InitializeComponent();
}

[WebMethod(EnableSession = true)]
public string HelloWorld()
{
if (!IsLoggedIn())
throw new Exception("User is not logged in!!!");
else
return "Hello World!";
}

private bool IsLoggedIn()


{
if (Session["username"] != null)
return true;
else
return false;
}

[WebMethod(EnableSession = true)]
public bool AuthenticateUser(string username, string password)
{

14
bool valid = Membership.ValidateUser(username, password);

if (valid)
{
FormsAuthentication.SetAuthCookie(username, false);
Session["username"] = username;
}
else
Session["username"] = null;

return valid;
}

[WebMethod]
public List<Athlete> ReadAthletes()
{
List<Athlete> athletes = new List<Athlete>();
cn.Open();

using (SqlCommand cmd = new SqlCommand("select * from


Athletes", cn))
{
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();

if (rdr.HasRows)
{
Athlete athlete;
while (rdr.Read())
{
athlete = new Athlete();
athlete.AthleteId =
int.Parse(rdr["AthleteId"].ToString());
athlete.FirstName = rdr["FirstName"].ToString();
athlete.LastName = rdr["LastName"].ToString();
athlete.Address = rdr["Address"].ToString();
athlete.City = rdr["City"].ToString();
athlete.State = rdr["State"].ToString();
athlete.Zip = rdr["Zip"].ToString();

athletes.Add(athlete);
}
}
}
cn.Close();
cn.Dispose();

return athletes;
}

[WebMethod]
public void SaveAthlete(Athlete athlete)
{

string sqlText = string.Empty;

15
if (athlete.AthleteId > 0)
sqlText = "update Athletes set FirstName=@FirstName,
LastName=@LastName, Address=@Address, City=@City, State=@State,
Zip=@Zip where AthleteId = @AthleteId";
else
sqlText = "insert into Athletes (FirstName, LastName,
Address, City, State, Zip) values (@FirstName, @LastName, @Address,
@City, @State, @Zip)";

cn.Open();

using (SqlCommand cmd = new SqlCommand(sqlText, cn))


{
cmd.Parameters.Add(new SqlParameter("@FirstName",
athlete.FirstName));
cmd.Parameters.Add(new SqlParameter("@LastName",
athlete.LastName));
cmd.Parameters.Add(new SqlParameter("@Address",
athlete.Address));
cmd.Parameters.Add(new SqlParameter("@City",
athlete.City));
cmd.Parameters.Add(new SqlParameter("@State",
athlete.State));
cmd.Parameters.Add(new SqlParameter("@Zip", athlete.Zip));
cmd.Parameters.Add(new SqlParameter("@AthleteId",
athlete.AthleteId));
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
cn.Close();
cn.Dispose();

[WebMethod]
public void DeleteAthlete(Athlete athlete)
{
string sqlText = "delete from Athletes where AthleteId =
@AthleteId";

cn.Open();

using (SqlCommand cmd = new SqlCommand(sqlText, cn))


{
cmd.Parameters.Add(new SqlParameter("@AthleteId",
athlete.AthleteId));
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
cn.Close();
cn.Dispose();
}

16
Due to limited time to complete these modules and exercises, you can
create user accounts by testing the Web service and invoking the
CreateUser Web method.

Exercise: Add a Service Reference

Duration: 5 to 10 minutes.

In this exercise, you will add a service reference to the Silverlight project.

1. The Silverlight project must be able to deserialize objects as they are sent from
the Web service. Hence, a copy of the object must be available for the Silverlight
application to inspect. When a service reference is created for the Web project in
the Silverlight project, any custom classes are made available to the Silverlight
project.
2. Right-click the Silverlight project in the Solution Explorer and select Add Service
Reference.
3. From the Add Service Reference dialog, select the Discover button to discover
services in the current solution. Assign a name to the service and click OK.
4. Before we can fully use the database and Web service that are in place, we must
build some classes and controls for the Silverlight application. In a future lesson
("Securing Silverlight Applications"), we will build a class that will be used to
track a user's security credentials and login status.

Exercise: Build an RSS reader

Duration: 30 to 45 minutes.

In this exercise, you will use Silverlight to create a simple RSS reader. Feel free to extend
the exercise to improve the lab in ways that you see fit.

1. Start or open Visual Studio 2008.


2. Create a new Silvelight project and select the option to create a separate Web
application test harness project. The project will serve as an RSS feed reader so
name it accordingly.
3. Add a reference to the Silverlight syndication assemblies by right-clicking the
Silverlight project (not the Web test harness project) in the Solution Explorer and
selecting Add Reference. On the .NET tab of the Add Reference dialog, scroll to
the System.ServiceModel.Syndication assembly and select OK.
4. Right-click Page.xaml in the Solution Explorer and select View Code. At the top
of the code behind, add using statements for the System.Xml namespace and for
the System.ServiceModel.Syndication namespace.
5. In the Solution Explorer, right-click the Page.xaml Silverlight control located in
the Silverlight project and select the option to Edit in Expression Blend.
6. Design the Silverlight control so that it contains at least a TextBox control for
entering the URL to use to acquire an RSS feed and a Button control for
submitting and acquiring the feed. Also add a control for displaying the feed

17
entries as they are acquired. In the sample application, a ScrollViewer control was
added and a TextBlock control was added to the ScrollViewer as shown in the
figure below.

7. Once you have completed designing the Silverlight control, close Expression
Blend and return to Visual Studio.
8. In the Page.xaml code behind, in the Page constructor, just after the
InitializeComponent() method call, add code to create a new HttpWebRequest to
the RSS URL as shown in the code snippet below:

HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(new


Uri(txtURL.Text));

9. Next, just after that line, add a line of code that asynchronously acquires the feed
and assigns a callback handler as shown in the snippet below:

httpRequest.BeginGetResponse(new AsyncCallback(HttpResponseHandler),
httpRequest);

10. Create the HttpResponseHandler callback method in the code behind file as
shown in the code snippet below:

public void HttpResponseHandler(IAsyncResult result)


{
// acquire the result.
HttpWebRequest httpRequest = (HttpWebRequest)result.AsyncState;

// acquire the feed response.

18
HttpWebResponse httpResponse =
(HttpWebResponse)httpRequest.EndGetResponse(result);

// load the response into an xml reader.


XmlReader xmlReader =
XmlReader.Create(httpResponse.GetResponseStream());

// load the response into a syndication feed.


SyndicationFeed feed = SyndicationFeed.Load(xmlReader);

// determine if any feed results were returned.


if (feed.Items.Count() > 0)
{
// reset the results text.
tbResults.Text = "";

// iterate through the feed results and display each.


foreach (SyndicationItem feedItem in feed.Items)
{
// display the result.
tbResults.Text += feedItem.Title.Text + Environment.NewLine;
tbResults.Text += "Published on: " +
feedItem.PublishDate.Date.ToShortDateString() + " | Last updated at:" +
feedItem.LastUpdatedTime.Date.ToShortTimeString() +
Environment.NewLine;
}
}
else
{
// notify the user that no feed results were returned.
tbResults.Text = "no feed results to display...";
}
}

11. Keep in mind when entering the URL for an RSS feed to acquire that the server
hosting the feed must opt-in to cross-domain access by providing a
Clientaccesspolicy.xml or Crossdomain.xml file at the root of the domain.
12. Press F5 to test the application.

Exercise: Use an Azure Service

Duration: 30 to 45 minutes.

In this exercise, you will use Silverlight to call the Live Search component of the Azure
Services Platform.

1. Go to http://search.live.com/developers and create an API ID. Copy your API ID


to the clipboard for the next steps.
2. Start or open Microsoft Visual Studio.
3. Create a new Silverlight solution named "LiveSearchAzure"

19
4. In the LiveSearchAzure.Web project, right-click and select "Add Service
Reference" and then enter the following URL, where MY_APP_ID is the API ID
that you were given in step 1. Name the Web Reference "LiveSearchService"

http://api.search.live.net/search.wsdl?MY_APP_ID

5. In the Web Project, Create a new Silverlight-Enabled WCF Web Service and
name it LiveSearchWrapper.svc
6. At the top of the LiveSearchWrapper.svc.cs file, add a using statement for the
proxy namespace:

using LiveSearchAzure.Web.LiveSearchService;

7. In the Web Service, Add a new WebMethod to search for Web Pages, and a new
Class to store and return results. IMPORTANT: Be sure to replace MY_APP_ID
with your Live Search API ID from Step 1.

[OperationContract]
public List<SearchResult> DoSearch(string search)
{
LiveSearchService.LiveSearchPortTypeClient s = new
LiveSearchPortTypeClient();

SearchRequest request = new SearchRequest();

// BE SURE TO ENTER _YOUR_ APP ID HERE!!!


request.AppId = "MY_APP_ID";
request.Query = search;
request.Sources = new SourceType[] { SourceType.Web };

request.Version = "2.0";
request.Market = "en-us";
request.Adult = AdultOption.Moderate;
request.AdultSpecified = true;

SearchResponse response = s.Search(request);

// create a collection of results


List<SearchResult> lstWebPages = new List<SearchResult>();

foreach (WebResult foundItem in response.Web.Results)


{
// web page hit
SearchResult result = new SearchResult();
result.ResultUrl = foundItem.Url;
result.Description = foundItem.Description;
lstWebPages.Add(result);
}

// send 'em down to the client


return lstWebPages;

20
}

public class SearchResult


{
public int HitNumber { get; set; }
public string ResultUrl { get; set; }
public string ImageUrl { get; set; }
public string Description { get; set; }
public double ImageHeight { get; set; }
public double ImageWidth { get; set; }
}

8. In the Silverlight Project, right-click the Service References node in Solution


Explorer and select "Add Service Reference." Click the Discover Button, select
the LiveSearchWrapper service, and enter "LiveSearchWrapper" for the
Namespace textbox. Then click the OK button.
9. Open Page.xaml and add some controls and layout INSIDE the <Grid> to search
and display. Note that we are adding a search box, a search button, and a nicely
formatted data template to the ListBox rows:

<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<StackPanel Orientation="Horizontal">
<TextBox x:Name="txtSearch" Width="200" />
<Button x:Name="btnSearch" Content="Search" />

</StackPanel>

<ListBox x:Name="lstResults" Grid.Row="1" Height="257"


Width="388" RenderTransformOrigin="0.5,0.5" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5,5,5,5"
Width="250">
<HyperlinkButton NavigateUri="{Binding
Path=ResultUrl}" TargetName="_blank" Content="{Binding Path=ResultUrl}"
/>
<TextBlock Text="{Binding Path=Description}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

10. Add a Click Event handler to btnSearch like so:

private void btnSearch_Click(object sender, RoutedEventArgs e)


{
DoSearch();
}

21
11. Add code to call the web service DoSearch method asynchronously:

private void DoSearch()


{
LiveSearchWrapper.LiveSearchWrapperClient webSvc = new
LiveSearchWrapper.LiveSearchWrapperClient();
webSvc.DoSearchCompleted += new
EventHandler<LiveSearchWrapper.DoSearchCompletedEventArgs>(webSvc_DoSea
rchCompleted);
webSvc.DoSearchAsync(txtSearch.Text);
}

void webSvc_DoSearchCompleted(object sender,


LiveSearchWrapper.DoSearchCompletedEventArgs e)
{
lstResults.ItemsSource = e.Result;
}

12. Run the application and try entering a search term, then click the Search button.

Networking In Silverlight Conclusion


In this lesson of the Silverlight tutorial, you

• Learned about networking protocols available when using Silverlight


• Created a Silverlight application to read and display an RSS feed

22

Anda mungkin juga menyukai