(For more resources on silverlight, see here.)
Looking at the namespaces and classes in the Silverlight assemblies, it’s easy to see that there are no ADO.NET-related classes available in Silverlight. Silverlight does not contain a DataReader, a DataSet, or any option to connect to a database directly. Thus, it’s not possible to simply define a connection string for a database and let Silverlight applications connect with that database directly.
The solution adds a layer on top of the database in the form of services. The services that talk directly to a database (or, more preferably, to a business and data access layer) can expose the data so that Silverlight can work with it. However, the data that is exposed in this way does not always have to come from a database. It can come from a third-party service, by reading a file, or be the result of an intensive calculation executed on the server.
Silverlight has a wide range of options to connect with services. This is important as it’s the main way of getting data into our applications. In this article, we’ll look at the concepts of connecting with several types of services and external data.
We’ll start our journey by looking at how Silverlight connects and works with a regular service. We’ll see the concepts that we use here recur for other types of service communications as well. One of these concepts is cross-domain service access. In other words, this means accessing a service on a domain that is different from the one where the Silverlight application is hosted. We’ll see why Microsoft has implemented cross-domain restrictions in Silverlight and what we need to do to access externally hosted services.
Next, we’ll talk about working with the Windows Azure Platform. More specifically, we’ll talk about how we can get our Silverlight application to get data from a SQL Azure database, how to communicate with a service in the cloud, and even how to host the Silverlight application in the cloud, using a hosted service or serving it from Azure Storage.
Finally, we’ll finish this chapter by looking at socket communication. This type of communication is rare and chances are that you’ll never have to use it. However, if your application needs the fastest possible access to data, sockets may provide the answer.
Applies to Silverlight 3, 4 and 5
If we need data inside a Silverlight application, chances are that this data resides in a database or another data store on the server. Silverlight is a client-side technology, so when we need to connect to data sources, we need to rely on services. Silverlight has a broad spectrum of services to which it can connect.
In this recipe, we’ll look at the concepts of connecting with services, which are usually very similar for all types of services Silverlight can connect with. We’ll start by creating an ASMX webservice—in other words, a regular web service. We’ll then connect to this service from the Silverlight application and invoke and read its response after connecting to it.
In this recipe, we’ll build the application from scratch. However, the completed code for this recipe can be found in the Chapter07/SilverlightJackpot_Read_Completed folder in the code bundle that is available on the Packt website.
We’ll start to explore the usage of services with Silverlight using the following scenario. Imagine we are building a small game application in which a unique code belonging to a user needs to be checked to find out whether or not it is a winning code for some online lottery. The collection of winning codes is present on the server, perhaps in a database or an XML file. We’ll create and invoke a service that will allow us to validate the user’s code with the collection on the server. The following are the steps we need to follow:
public class CodesRepository
{
private List<string> winningCodes;
public CodesRepository()
{
FillWinningCodes();
}
private void FillWinningCodes()
{
if (winningCodes == null)
{
winningCodes = new List<string>();
winningCodes.Add("12345abc");
winningCodes.Add("azertyse");
winningCodes.Add("abcdefgh");
winningCodes.Add("helloall");
winningCodes.Add("ohnice11");
winningCodes.Add("yesigot1");
winningCodes.Add("superwin");
}
}
public List<string> WinningCodes
{
get
{
return winningCodes;
}
}
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class JackpotService : System.Web.Services.WebService
{
List<string> winningCodes;
public JackpotService()
{
winningCodes = new CodesRepository().WinningCodes;
}
[WebMethod]
public bool IsWinningCode(string code)
{
if(winningCodes.Contains(code))
return true;
return false;
}
}
<StackPanel>
<TextBox x_Name="CodeTextBox"
Width="100"
Height="20">
</TextBox>
<Button x_Name="CheckForWinButton"
Content="Check if I'm a winner!"
Click="CheckForWinButton_Click">
</Button>
<TextBlock x_Name="ResultTextBlock">
</TextBlock>
</StackPanel>
private void CheckForWinButton_Click(object sender,
RoutedEventArgs e)
{
JackpotService.JackpotServiceSoapClient client = new
SilverlightJackpot.JackpotService.JackpotServiceSoapClient();
}
client.IsWinningCodeCompleted += new EventHandler
<SilverlightJackpot.JackpotService.
IsWinningCodeCompletedEventArgs>
(client_IsWinningCodeCompleted);
client.IsWinningCodeAsync(CodeTextBox.Text);
void client_IsWinningCodeCompleted(object sender,
SilverlightJackpot.JackpotService.
IsWinningCodeCompletedEventArgs e)
{
bool result = e.Result;
if (result)
ResultTextBlock.Text = "You are a winner! Enter your data
below and we will contact you!";
else
ResultTextBlock.Text = "You lose... Better luck next time!";
}
As it stands, the current version of Silverlight does not have support for using a local database. Silverlight thus needs to rely on external services for getting external data. Even if we had local database support, we would still need to use services in many scenarios. The sample used in this recipe is a good example of data that would need to reside in a secure location (meaning on the server). In any case, we should never store the winning codes in a local database that would be downloaded to the client side.
Silverlight has the necessary plumbing on board to connect with the most common types of services. Services such as ASMX, WCF, REST, RSS, and so on, don’t pose a problem for Silverlight. While the implementation of connecting with different types of services differs, the concepts are similar.
In this recipe, we used a plain old web service. Only the methods that are attributed with the WebMethodAttribute are made available over the service. This means that even if we create a public method on the service, it won’t be available to clients if it’s not marked as a WebMethod. In this case, we only create a single method called IsWinningCode, which retrieves a list of winning codes from a class called CodesRepository. In real-world applications, this data could be read from a database or an XML file. Thus, this service is the entry point to the data.
For Silverlight to work with the service, we need to add a reference to it. When doing so, Visual Studio will create a proxy class. Visual Studio can do this for us because the service exposes a Web Service Description Language (WSDL) file. This file contains an overview of the methods supported by the service. A proxy can be considered a copy of the server-side service class, but without the implementations. Instead, each copied method contains a call to the actual service method. The proxy creation process carried out by Visual Studio is the same as adding a service reference in a regular .NET application.
However, invoking the service is somewhat different. All communication with services in Silverlight is carried out asynchronously. If this wasn’t the case, Silverlight would have had to wait for the service to return its result. In the meantime, the UI thread would be blocked and no interaction with the rest of the application would be possible.
To support the asynchronous service call inside the proxy, the IsWinningCodeAsync method as well as the IsWinningCodeCompleted event is generated. The IsWinningCodeAsync method is used to make the actual call to the service. To get access to the results of a service call, we need to define a callback method. This is where the IsWinningCodeCompleted event comes in. Using this event, we define which method should be called when the service returns (in our case, the client_IsWinningCodeCompleted method). Inside this method, we have access to the results through the Result parameter, which is always of the same type as the return type of the service method.
Apart from reading data, we also have to persist data. In the next recipe, Persisting data using a standardized service, we’ll do exactly that.
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…