Networking In Silverlight
- How networking and external communication is integrated into Silverlight
- About sockets programming and how it is used to secure Silverlight networking
- How to consume a Web service or WCF service from Silverlight
- To consume services using various networking protocols and the benefits of each protocol
- How to use other protocols in Silverlight such as syndication protocols
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(see footnote)
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 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:
- 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.
- 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.
- 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.
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.
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.
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(see footnote)
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.
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
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>
- 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.
- 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>
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.
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.
Exercise: Create the Athlete Database
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.
- Start or open Visual Studio 2008.
- 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.
- 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\AthleteManager_Web\App_Data
Exercise: Create the Athlete Class
In this exercise, you will create a class that represents an athlete.
- Add a new class to the Web project (not the Silverlight project).
- 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; } 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; this.Height = height; this.Weight = weight; this.Biography = biography; this.Notes = notes; } #endregion }
Exercise: Create the Sport Class
In this exercise, you will create a class that represents a sport.
- Add a new class to the Web project (not the Silverlight project).
- 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
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.
- Add a new Web service (or WCF service, if desired) to the Web project (not the Silverlight project).
- 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"].ConnectionString); 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) { 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; 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(); } } - 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
In this exercise, you will add a service reference to the Silverlight project.
- 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.
- Right-click the Silverlight project in the Solution Explorer and select Add Service Reference.
- 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.
- 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
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.
- Start or open Visual Studio 2008.
- 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.
- 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.
- 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.
- 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.
- 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 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.
- Once you have completed designing the Silverlight control, close Expression Blend and return to Visual Studio.
- 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));
- 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);
- 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. 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..."; } } - 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.
- Press F5 to test the application.
Exercise: Use an Azure Service
In this exercise, you will use Silverlight to call the Live Search component of the Azure Services Platform.
- Go to http://search.live.com/developers and create an API ID. Copy your API ID to the clipboard for the next steps.
- Start or open Microsoft Visual Studio.
- Create a new Silverlight solution named "LiveSearchAzure"
- 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
- In the Web Project, Create a new Silverlight-Enabled WCF Web Service and name it LiveSearchWrapper.svc
- At the top of the LiveSearchWrapper.svc.cs file, add a using statement for the
proxy namespace:
using LiveSearchAzure.Web.LiveSearchService; - 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; } 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; } } - 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.
- 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> - Add a Click Event handler to btnSearch like so:
private void btnSearch_Click(object sender, RoutedEventArgs e) { DoSearch(); } - 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_DoSearchCompleted); webSvc.DoSearchAsync(txtSearch.Text); } void webSvc_DoSearchCompleted(object sender, LiveSearchWrapper.DoSearchCompletedEventArgs e) { lstResults.ItemsSource = e.Result; } - 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
Footnotes
-
For more information on Silverlight and sockets programming, visit the MSDN article entitled Working with Sockets located at http://msdn.microsoft.com/en-us/library/cc296248(VS.95).aspx.
-
Be aware that sockets programming is low-level, does require some coding and lacks the more robust features of some of the other networking standards.
-
For more information on WSDL, visit the W3C website: http://www.w3.org/TR/wsdl.
-
For more information on JSON, visit Webucator's Ajax tutorial: http://www.learn-ajax-tutorial.com/Json.cfm.