This article would be a natural continuation of my previous post on “Connecting Azure and Windows Phone through OData” and show a different way of leveraging Azure cloud services for your Mobile applications.
Also, Peter Kuhn (aka MisterGoodcat) did a brilliant article series on “Getting Ready for the Windows Phone 7 Exam 70-599” and I wanted to expand on the Data Access Strategy section by talking more about connectivity to Windows Azure.
Prelude
In the last article (here), we talked about how OData can really be very handy when providing cloud data backend support for a variety of mobile & web platforms. We simply had a SQL Azure database & used the SQL Azure services to expose the data through an OData feed straight out of Azure, which had full support for CRUD operations given the right roles. However, this approach might seem brute-force for some project needs. For one, we did not have any granularity over how much of a Table’s data we wanted to expose; it was all or nothing. Also, what if you did not want to expose all of the data, but just a few operations on it? And what if you really wanted to have your database on-premise; yet use the ubiquitous Azure services to empower Mobile applications to perform operations on the data? That’s what we talk about in this installment :)
The Database
Now, let’s say we are trying to write a Windows Phone application that interacts with data housed in a remote Database. This is obviously quite a common scenario, because it allows for the data to be utilized/consumed on other platforms. Now, for this demo, I chose to use a simple Database hosted in SQL Azure, since I find it very easy to do so. It is important to note that this Database can be just about anything, on-premise or in the cloud; as long as .NET can connect to it, we should be fine. That said, here’s my Azure Portal set-up:
You’ll notice that I have used one of my Azure subscriptions to create a “PatientData” Database in my SQL Azure server .. this will house our super-secret patient information :) Now, before moving on, you may want to copy the appropriate Connection String to this Database so that we may connect to it remotely. Now, let’s get inside our “PatientData” Database and create a simple table, also called “PatientData”, & fill in some dummy data like here:
The data schema is over-simplified: the ID field is an auto-incrementing integer & we just keep track of Patient “Name” & “Condition” – told you we were dealing with sensitive data :)
Again, this Database could be anywhere. What we want to do however, is to have a Service that is globally accessible from mobile applications and one that interacts with the backend Database only supporting agreed-upon operations.
The Service
We want a simple a service that interacts with our backend Database & one that can be consumed from a Windows Phone application. Again, Windows Azure seems like one of the easiest places to host such a service and make it globally accessible. So, here’s our goal:
- Create a Windows Azure cloud project
- Use ADO.NET Entity Data Model as an ORM Mapper to our backend Database
- Create a simple WCF Service inside of a Azure WebRole
- Utilize the ORM context to expose specific operations through the WCF service
- When all is done & working, host the WCF service in Azure
This is how we start:
Next step, we need a way to map the relational Database table into .NET world objects .. this is where an Object Relational Mapper [ORM] steps in. For our purpose, let’s add the ADO.NET Entity Data Model to our project, like below:
As a part of adding the ADO.NET Entity Data Model, you step through a wizard that is essentially going to point to a Database table to reflect upon & provides column-mapping as Properties to a .NET object. This is where we get to utilize the “Connection String” that we had copied from the Azure Portal, so that we can point ADO.NET Entity Data Model to our SQL Azure table, as shown in the steps below:
The last image shows generated “.edmx” file that ADO.NET Data Entity Model created, on being pointed to our Database Table. That’s it! Now we have “PatientData” as an entity in our C# code. The final project structure should look like this:
Now, let’s define the “PatientService” Interface with exactly the operations we want to support & implement them. For this demo, I chose to do two – one that gets us a list of “Patients” & one that allows for adding “Patients”. Here’s the simple Interface:
1: namespace PatientService
2: {
3: [ServiceContract]
4: public interface IPatientServiceInterface
5: {
6: [OperationContract]
7: List<PatientData> GetPatientList();
8:
9: [OperationContract]
10: string AddPatient(PatientData newPatient);
11: }
12:
13: }
And the implementation:
1: namespace PatientService
2: {
3: public class PatientDataService : IPatientServiceInterface
4: {
5: #region "Interface Implementation"
6:
7: public List<PatientData> GetPatientList()
8: {
9: var context = new PatientDataEntities();
10: return context.PatientData.ToList<PatientData>();
11: }
12:
13: public string AddPatient(PatientData newPatient)
14: {
15: try
16: {
17: var context = new PatientDataEntities();
18: context.AddObject("PatientData", newPatient);
19:
20: context.SaveChanges();
21: return "Success!";
22: }
23: catch (Exception e)
24: {
25: return e.Message;
26: }
27: }
28:
29: #endregion
30: }
31: }
Notice how we are easily able to utilize the “PatientDataEntities” mapping provided by ADO.NET Entity Data Model as a “Context” within our service implementation. Now, with our service looking like it has all the needed pieces, we do some testing locally to make sure that the methods invoked do actually reach out to our SQL Azure Database & do what they are supposed to do. If satisfied, comes the next step of hosting our service in Azure for ubiquitous availability. This is where the “Windows Azure Project” template helps, as it has already provided an Azure wrapper for our WCF Service. Here the steps to host our simple service in Azure:
- Right Click on the “AzurePatientService” cloud project & select “Publish”
- Then, “Create Service Packages only”
- This should build our Project & produce two deliverables
- One is the Cloud Service Configuration File (.cscfg)
- Other, the actual Project package (.cspkg)
The steps are demonstrated below:
Once the deployment packages are created locally, you may want to copy the directory file path, as we shall need it in the next step. Now, to actually hosting the Service in Azure – Create a new “Hosted Service” in the Azure Portal, with appropriate settings. Notice how we use our local directory file path to point Azure where to pick up the Service Configuration & Project Package from. Also, for demo purposes, we are directly making our Service live in “Production”; actual Services may benefit from being tested in “Staging” before going to “Production”.
Now, little wait till Azure spins up the resources needed to host our Service & voila, we are live in Azure! Let’s hit the WCF endpoint to make sure our Service is properly hosted & its metadata is accessible. If you’re with me so far, you now know how to deploy & host simple WCF Services in Azure! The rest will be easy :)
The Windows Phone Client
Now that we have our WCF Service hosted & accessible in Azure, consuming it from our Windows Phone Mango application will be standard procedure. Let us aim to build a simple Windows Phone client that leverages the two operations supported by our Service – show list of “Patients” & ability to add new “Patients”. My demo UI looks like the following:
As we start building our Windows Phone client, one of our first steps would be to “Add Service Reference” to our Service, so that our project knows the metadata & exposes methods from the Service. This is as simple as copying the URL to our Azure-hosted Service & adding it as a Reference as below:
That’s it! .NET builds the proxies & we are ready to consume our Service methods. Here’s how we request the “List of Patients” from our Service:
1: PatientServiceInterfaceClient PatientServiceClient = new PatientServiceInterfaceClient();
2: PatientServiceClient.GetPatientListCompleted += new EventHandler<GetPatientListCompletedEventArgs>(PatientServiceClient_GetPatientListCompleted);
3: PatientServiceClient.GetPatientListAsync();
4:
5: void PatientServiceClient_GetPatientListCompleted(object sender, GetPatientListCompletedEventArgs e)
6: {
7: ObservableCollection<PatientData> patientList = e.Result;
8: this.lstPatients.ItemsSource = patientList;
9: }
And the little XAML code to bind the results to UI:
1: <ListBox Name="lstPatients" Margin="20,0,0,60">
2: <ListBox.ItemTemplate>
3: <DataTemplate>
4: <StackPanel Orientation="Vertical">
5: <StackPanel Orientation="Horizontal">
6: <Image Source="/Images/Medicine.png" Height="50" Width="50"/>
7: <TextBlock Text="{Binding Name}" FontSize="40" Margin="10,0,0,0" Style="{StaticResource PhoneTextAccentStyle}"/>
8: </StackPanel>
9: <TextBlock Text="{Binding Condition}" FontSize="32" Margin="60,0,0,20"/>
10: </StackPanel>
11: </DataTemplate>
12: </ListBox.ItemTemplate>
13: </ListBox>
Here’s how we use the Service to “Add Patients”:
1: // Instantiate the client.
2: PatientServiceInterfaceClient PatientServiceClient = new PatientServiceInterfaceClient();
3:
4: PatientData newPatient = new PatientData();
5: newPatient.Name = this.txtName.Text.Trim();
6: newPatient.Condition = this.txtCondition.Text.Trim();
7:
8: // Invoke method asynchronously.
9: PatientServiceClient.AddPatientCompleted += new EventHandler<AddPatientCompletedEventArgs>(PatientServiceClient_AddPatientCompleted);
10: PatientServiceClient.AddPatientAsync(newPatient);
11:
12: void PatientServiceClient_AddPatientCompleted(object sender, AddPatientCompletedEventArgs e)
13: {
14: if (e.Result == "Success!")
15: {
16: MessageBox.Show("Voila, Saved to the Cloud :)", "All Done!", MessageBoxButton.OK);
17: this.NavigationService.Navigate(new Uri("/PatientList.xaml", UriKind.Relative));
18: }
19: else
20: {
21: MessageBox.Show(e.Result, "Save Error!", MessageBoxButton.OK);
22: this.NavigationService.Navigate(new Uri("/PatientList.xaml", UriKind.Relative));
23: }
24: }
Conclusion
So, what we talked about so far was ways in which Azure can be of much benefit in hosting WCF Services, which in turn communicate with remote Databases & could easily provide CRUD operation functionality to your backend server. You could take this concept & literally make your services do anything you want .. Azure just makes hosting a snap, with high availability & failover. And, each of these Services can be easily consumed from Mobile applications, like the Windows Phone one in our case. Hope this article demonstrated some techniques & got you thinking on how to Service-enable your Mobile applications. Thanks a lot for reading & cheers to SilverlightShow.
About Author
Samidip Basu (@samidip ) is a technologist & gadget-lover working as a Manager & Solutions Lead for Sogeti out of the Columbus OH Unit. Having worked on WP7 since CTP days, he now spends much of his time in spreading the word to discover the full potential of the Windows Phone platform & cloud-based mobile solutions in general. He passionately runs the Central Ohio Windows Phone User Group (http://cowpug.org/) and can be found with atleast a couple of hobbyist projects at any time. His spare times call for travel and culinary adventures with the wife. Find out more at http://samidipbasu.com/
.