“Data from cloud on the phone “, it may appear as a buzzing sentence to you. In this post, I try to minimize complexity of accessing data from cloud to be specific from SQL Azure in Windows Phone. In this post I will walkthrough step by step accessing data from SQL Azure in Windows Phone.
I have divided task in three parts.
We will expose all the operation on Student database residing in SQL Azure as WCF REST Service. In this case REST is working on JSON data.
Setting up project
Very first let us set up the project. We want to expose operation as WCF Service hosted in Windows Azure. So to do that, you need to create WCF Service Role.
Creating Data Model
We are going to create DataModel using LINQ to SQL Class. To create DataModel right click on project then select add new item and choose LINQ to SQL Class form Data tab.
Next you need to choose the option Server explorer and add a new connection. In Add new connection windows provide database information for SQL Azure.
From drop down you choose database of your choice. In this case I am going to select Student database. After selecting database on the designer, I am dragging and dropping table Person. On the designer (dbml) you should have Person class .As of now we have created DataModel. In solution explorer you will find dbml and dbml.cs file has been created.
Creating Service
Data Transfer Object class represents entity from Data Model we want to expose as part of service contract. We need to create Data Transfer Object class. This class will act as Data Contract between Service and Client. To add a Data Transfer Object class go ahead and add a new class to project as below.
PersonDTO.cs
using System.Runtime.Serialization; namespace RESTJSONStudentsData { [DataContract] public class PersonDTO { [DataMember] public string StudentId { get; set; } [DataMember] public string FirstName { get; set; } [DataMember] public string LastName { get; set; } } }
We have created Data Contract. Now we need to create Service Contract. Service Contract must be attributed to behave as WCF REST Service. I have set request and response format as JSON.
IService1.cs
using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Web; namespace RESTJSONStudentsData { [ServiceContract] public interface IService1 { [OperationContract] [WebGet(UriTemplate="/Persons", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json] List<PersonDTO> GetPersons(); } }
Now we need to implement the service. In Service implementation, I am querying Person table of Student database using LINQ and constructing List of PersonDTO.
Service1.svc.cs
using System.Collections.Generic; using System.Linq; namespace RESTJSONStudentsData { public class Service1 : IService1 { public List<PersonDTO> GetPersons() { DataClasses1DataContext context = new DataClasses1DataContext(); List<PersonDTO> result = (from r in context.Persons select new PersonDTO { FirstName = r.FirstName, LastName = r.LastName, StudentId = r.PersonID.ToString() }).ToList<PersonDTO>(); return result; } } }
Next in this section we need to configure service. We need to configure service webHttpBinding to eanble it as REST Service. So in Web.Config we need to do the below changes.
Web.Config
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name ="servicebehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="restbehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> <services> <service name ="RESTJSONStudentsData.Service1" behaviorConfiguration="servicebehavior" > <endpoint name ="RESTEndPoint" contract ="RESTJSONStudentsData.IService1" binding ="webHttpBinding" address ="rest" behaviorConfiguration ="restbehavior"/> </service> </services> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>
After configuring, Service ready for hosting. We need to host it in Windows Azure Portal. For that right click on Windows Azure project and select Package and Upload this package to one of the hosted service. Up to this step we have created and hosted WCF REST Service returning JSON.
Consuming Service in Windows Phone
To consume REST Service in Windows Phone 7 and then parse JSON, you need to add below references in Windows Phone 7 project.
We need a class to represent PersonDTO class .For that makes a class called Person at client side.
Person.cs
namespace PhoneApp11 { public class Person { public string StudentId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } }
As the design of the page I have put a ListBox. Data returned from cloud table will get bind to this ListBox.
MainPage.xaml
<phone:PhoneApplicationPage x:Class="PhoneApp11.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded"> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="data from SQL Azure" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="students" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <ListBox x:Name="lstPerson" > <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding LastName}" Style="{StaticResource PhoneTextTitle1Style}" /> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding StudentId}" Style="{StaticResource PhoneTextGroupHeaderStyle}" /> <TextBlock Text="{Binding FirstName}" Style="{StaticResource PhoneTextTitle2Style}" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </phone:PhoneApplicationPage>
We need to make a call to the service and on download of JSON data as string; we need to parse JSON using System.RunTime.Serlization.JSON
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Net; using System.Windows; using Microsoft.Phone.Controls; using System.IO; using System.Runtime.Serialization.Json; using System.Text; namespace PhoneApp11 { public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); } private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) { WebClient proxy = new WebClient(); proxy.DownloadStringCompleted += new DownloadStringCompletedEventHandler(proxy_DownloadStringCompleted); proxy.DownloadStringAsync(new Uri("http://debugmodesqlazurejson.cloudapp.net/Service1.svc/rest/Persons")); } void proxy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { Stream stream = new MemoryStream(Encoding.Unicode.GetBytes(e.Result)); DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(List<Person>)); List<Person> result = (List < Person >) obj.ReadObject(stream); lstPerson.ItemsSource = result; } } }
In above code we are creating DataContractJsonSerializer object and passing List of Person to deseriliaze because service is returning list of PersonDTO. And as mentioned earlier Person class is representing PersonDTO class. Now go ahead and press F5 to run the application. You should be getting details of Person table from School database residing on SQL Azure.
In later post we will explore further to perform other CRUD operations. I hope this post is useful. Thanks for reading.
Follow @debug_mode
Leave a Reply