Windows Phone - 與Mobile Service - 資料庫存取,交個朋友

Windows Phone - 與Mobile Service - 資料庫存取,交個朋友

過去在撰寫WP的App時,如果程式的內容物來自Server的話總是要去找一台Server放置自己撰寫好的Service,

對於有主機代管或家裡有強大Server的開發者也許不是問題,但如果是像我這種小型的開發者其實就沒有這麼方便。

好在現在MS在Azure上推出了Mobile Service,透過熟悉的REST API的方式與它進行交互,維護自訂好的Data Table與Object

相當的方便與實用,因此,該篇將撰寫個人在與Mobile Service交流的過程。

 

〉Mobile Service

    參考<如何透過WP7存取Mobile Services(BETA)>所介紹的方式,建立一個Mobile Service與建立個Table,

以本文範例則是建立一個Reject的物件。透過圖示加以說明:

 

(a) 建立一個Mobile Service

     00

(b) 建立一個Table與定義該Table Schema

     01

     02

      該Table命名為:Reject,具有欄位:id、Icon、Responser、DateTime、PhoneNumber、Message。

 

(c) 設定Table的操作權限(需透過application key進行操作)

     03

從以上定義好的Mobile Service與要操作的Table,接下來要針對Table內的物件進行操作。

 

 

〉WP7 with Mobile Service

    由於Mobile Service沒有提供WP 7操作的SDK,所以需要透過REST API與JSON來進行操作,操作前準備一下相關的URI:

‧Mobile Service Name:https://wpproject.azure-mobile.net/

‧操作資料表:Reject

‧id(編號):按照資料儲存的id欄位值為主;

REST API URI
GET - 取得所有資料 https://[Mobile Service Name].azure-mobile.net/tables/[Table Name]/
GET - 得指定資料 https://[Mobile Service Name].azure-mobile.net/tables/[Table Name]/[id(編號)]
POST - 新增一筆資料 https://[Mobile Service Name].azure-mobile.net/tables/[Table Name]/
PATCH - 更新指定資料 https://[Mobile Service Name].azure-mobile.net/tables/[Table Name]/[id(編號)]
DELETE - 刪除指定資料 https://[Mobile Service Name].azure-mobile.net/tables/[Table Name]/[id(編號)]

這些URI搭配我們將該資料表物件化後,再轉換成JSON發送給Mobile Service即可以完成以上五種的操作。

 

(a) 建立將物件與JSON互相轉換的類別

     詳細資料參考<[教學影片][研討會] Windows Azure Mobile Services 三部曲>的內容;

   1: //需加入"System.Runtime.Serialization"與"System.Servicemodel.Web"二個參考至專案
   2:  
   3: using System.Runtime.Serialization;
   4: using System.Runtime.Serialization.Json;
   5:  
   6: public class JsonHelper
   7: {
   8: /// <summary>
   9: /// Json to Object。
  10: /// </summary>
  11: /// <param name="pJson">Json</param>
  12: /// <param name="pType">Object Type</param>
  13: /// <returns>Object</returns>
  14: public static object JsonToObject(string pJson, Type pType)
  15: {
  16:     try
  17:     {
  18:         object tObj = null;
  19:         MemoryStream tMStream = new MemoryStream(Encoding.UTF8.GetBytes(pJson));
  20:         DataContractJsonSerializer tSer = new DataContractJsonSerializer(pType);
  21:         tObj = tSer.ReadObject(tMStream);
  22:         tMStream.Close();
  23:         return tObj;
  24:     }
  25:     catch (Exception)
  26:     {
  27:         throw;
  28:     }
  29: }
  30:  
  31: /// <summary>
  32: /// Object to Json。
  33: /// </summary>
  34: /// <param name="pObj">Object</param>
  35: /// <param name="pType">Object Type</param>
  36: /// <returns>Json</returns>
  37: public static string ObjectToJson(object pObj, Type pType)
  38: {
  39:     try
  40:     {                
  41:         MemoryStream tMStream = new MemoryStream();
  42:         DataContractJsonSerializer tSer = new DataContractJsonSerializer(pType);
  43:         tSer.WriteObject(tMStream, pObj);
  44:         byte[] tJson = tMStream.ToArray();
  45:         tMStream.Close();
  46:         return Encoding.UTF8.GetString(tJson, 0, tJson.Length);
  47:     }
  48:     catch (Exception)
  49:     {
  50:         throw;
  51:     }
  52: }

 

(b) 定義Reject資料表中的物件,並且加上Serialized的宣告

   1: //記得宣告該類別為DataContract。
   2: [DataContract()]
   3: public class MobileService_Reject
   4: {
   5:     // id為Mobile Service必要的欄位,需採用IgnoreDataMember來避免它產生代號。
   6:     [IgnoreDataMember()]
   7:     public int id { get; set; }
   8:     [DataMember()]
   9:     public string Icon { get; set; }
  10:     [DataMember()]
  11:     public string Responser { get; set; }
  12:     [DataMember()]
  13:     public string DateTime { get; set; }
  14:     [DataMember()]
  15:     public string PhoneNumber { get; set; }
  16:     [DataMember()]
  17:     public string Message { get; set; }
  18: }

 

(c) 利用REST API操作Reject資料表的資料

     c-1. 取得指定id = 1的資料表

   1: private void btnGet_Click(object sender, RoutedEventArgs e)
   2: {
   3:     WebClient tWebClient = new WebClient();
   4:     tWebClient.UploadStringCompleted += tWebClient_UploadStringCompleted;
   5:     tWebClient.DownloadStringCompleted += tWebClient_DownloadStringCompleted;
   6:  
   7:     //Get Reject Data
   8:     tWebClient.DownloadStringAsync(new Uri(gURI + "1"));
   9: }

    

    c-2. 新增一個新的資料

   1: private void btnInsert_Click(object sender, RoutedEventArgs e)
   2: {
   3:     WebClient tWebClient = new WebClient();
   4:     tWebClient.UploadStringCompleted += tWebClient_UploadStringCompleted;
   5:     tWebClient.DownloadStringCompleted += tWebClient_DownloadStringCompleted;
   6:  
   7:     //Insert Reject Data
   8:     tWebClient.Headers["Content-Type"] = "application/json"; 
   9:     tWebClient.Headers["X-ZUMO-APPLICATION"] = gAppKey;
  10:     tWebClient.UploadStringAsync(
  11:         new Uri(gURI), 
  12:         "POST",
  13:         JsonHelper.ObjectToJson(GetObject(), typeof(MobileService_Reject)));
  14: }

 

     c-3. 更新id=1的資料

   1: private void btnUpdate_Click(object sender, RoutedEventArgs e)
   2: {
   3:     WebClient tWebClient = new WebClient();
   4:     tWebClient.UploadStringCompleted += tWebClient_UploadStringCompleted;
   5:     tWebClient.DownloadStringCompleted += tWebClient_DownloadStringCompleted;
   6:  
   7:     //Update Reject Data
   8:     tWebClient.Headers["Content-Type"] = "application/json"; 
   9:     tWebClient.Headers["X-ZUMO-APPLICATION"] = gAppKey;
  10:     tWebClient.UploadStringAsync(
  11:         new Uri(gURI + "1"), 
  12:         "PATCH",
  13:         JsonHelper.ObjectToJson(GetObject(), typeof(MobileService_Reject)));
  14: }

 

     c-4. 刪除id=1的資料

   1: private void btnDelete_Click(object sender, RoutedEventArgs e)
   2: {
   3:     WebClient tWebClient = new WebClient();
   4:     tWebClient.UploadStringCompleted += tWebClient_UploadStringCompleted;
   5:     tWebClient.DownloadStringCompleted += tWebClient_DownloadStringCompleted;
   6:  
   7:     //Delete Reject Data
   8:     tWebClient.Headers["Content-Type"] = "application/json";
   9:     tWebClient.Headers["X-ZUMO-APPLICATION"] = gAppKey;
  10:     tWebClient.UploadStringAsync(
  11:         new Uri(gURI + "1"), 
  12:         "DELETE",
  13:         JsonHelper.ObjectToJson(GetObject(), typeof(MobileService_Reject)));
  14: }

 

     c-5. 處理DownloadStringCompleted與UploadStringCompleted

   1: void tWebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
   2: {
   3:     string tMsg = string.Empty;
   4:  
   5:     if (e.Error == null)
   6:     {
   7:         tMsg = e.Result;
   8:     }
   9:     else
  10:     {
  11:         tMsg = e.Error.Message;
  12:     }
  13:     Dispatcher.BeginInvoke(() =>
  14:     {
  15:         MessageBox.Show(tMsg, "Get Data from Azure", MessageBoxButton.OK);
  16:     });
  17:  
  18: }
  19:  
  20: void tWebClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
  21: {
  22:     string tMsg = string.Empty;
  23:  
  24:     if (e.Error == null)
  25:     {
  26:         tMsg = "Success";  
  27:     }
  28:     else
  29:     {
  30:         tMsg = e.Error.Message;
  31:     }
  32:     Dispatcher.BeginInvoke(() =>
  33:     {
  34:         MessageBox.Show(tMsg, "UploadString to Azure", MessageBoxButton.OK);
  35:     });
  36: }

以上是介紹透過WP7配合REST API存取Mobile Service中的資料表。

 

 

〉WP8 with Mobile Service

    如果WP8操作Mobile Service則不需像上方WP7這麼辛苦,可以直接透過Mobile Service上下載範例程式,如下圖:

   04

以下透過程式碼來加以說明:

(a) 建立一個Reject物件

   1: public class Reject
   2: {
   3:     //[IgnoreDataMember()]
   4:     public int id { get; set; }
   5:     [DataMember(Name = "Icon")]
   6:     public string Icon { get; set; }
   7:     [DataMember(Name = "Responser")]
   8:     public string Responser { get; set; }
   9:     [DataMember(Name = "DateTime")]
  10:     public string DateTime { get; set; }
  11:     [DataMember(Name = "PhoneNumber")]
  12:     public string PhoneNumber { get; set; }
  13:     [DataMember(Name = "Message")]
  14:     public string Message { get; set; }
  15:  
  16:     public string TitleData { get { return string.Format("{0}:{1}", Responser, DateTime); } }
  17: }

 

(b) 在WP8中的App.xaml.cs中宣告使用Mobile Service的參數

   1: public partial class App : Application
   2: {
   3:     public static MobileServiceClient MobileService = new MobileServiceClient(
   4:         "https://wpproject.azure-mobile.net/",
   5:         "{Application Key}"
   6:         );
   7: }

 

(c) 透過App.MobileService API來操作Reject物件

     c-1. 取得Reject的物件集合

   1: private MobileServiceCollectionView<Reject> items;
   2:  
   3: private IMobileServiceTable<Reject> todoTable = 
   4:                  App.MobileService.GetTable<Reject>();
   5:  
   6: private void RefreshTodoItems()
   7: {
   8:     // 透過App.MobileService取得指定Table Name的所有資料集合
   9:     items = todoTable.ToCollectionView();
  10:     ListItems.ItemsSource = items;
  11: }

 

     c-2. 新增Reject物件;(由於MobileService API採用Async機制,所以在方法上記得加上async)

   1: private async void InsertTodoItem(Reject todoItem)
   2: {    
   3:     await todoTable.InsertAsync(todoItem);
   4:     items.Add(todoItem);
   5: }

 

     c-3. 更新Reject物件;(由於MobileService API採用Async機制,所以在方法上記得加上async)

   1: private async void UpdateCheckedTodoItem(Reject item)
   2: {    
   3:     await todoTable.UpdateAsync(item);
   4:     items.Remove(item);
   5: }

透過Mobile Service API是不是非常方便呢,不用在去管HTTP的操作方式,因為這些內容均被包裝好了,

因此操作上只需管理物件的使用, 搭配GetTable()、InsertAsync()、UpdateAsync()、DeleteAsync()完成資料的操作。

 

[範例程式]

======

以上是介紹透過WP8與WP7操作Mobile Service的學習筆記,其實WP8裡擁有Azure包裝好的SDK比較方便,

但學習透過WP7以REST API的方式進行交互也是個不錯的練習,希望對大家有所幫助。謝謝。

 

References:

如何透過WP7存取Mobile Services(BETA)

Windows Phone 7 Azure Mobile services

Using Azure Mobile Services with Windows Phone

Windows Phone 7存取Mobile Service問題

isdaviddong - 教學影片 (重要)

Windows Azure示範教學:建立基本WorkerRole WP7 Push Notification訊息發送

http://www.codeproject.com/Articles/585792/Android-and-iOS-Mobile-Device-Development-with-Azu

 

Dotblogs Tags: ,