當您已經建立起 Xamarin.Forms 開發專案與加入了相關套件與插件,並且也在不同的專案內加入了分類用的資料夾,接下來,您將會需要將基礎服務開發出來。
在這個階段的練習,您將會需要完成學會底下需求:
- 建立資料模型 (Model)
- 建立全域靜態變數
- 建立呼叫後端 Web API 的服務類別
- 建立判斷現在是否在Debug模式或者Release模式的介面與其實作
- 建立全域XAML樣式
這篇章節的練習專案的原始程式碼將會存放在 GitHubhttps://github.com/vulcanlee/XFAppSample/tree/master/XFDoggy/2.InfraService 內
建立資料模型 (Model)
使用者類別
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Models
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
User
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
User.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Models
{
public class User
{
public int ID { get; set; }
public string Account { get; set; }
public string Password { get; set; }
}
}
使用者認證與認證結果類別
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Models
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
AuthUser
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
AuthUser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Models
{
public class AuthUser
{
public string Account { get; set; }
public string Password { get; set; }
}
public class AuthUserResult
{
public bool Status { get; set; }
}
}
差旅費用類別項目定義類別
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Models
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
TravelExpensesCategory
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
TravelExpensesCategory.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Models
{
public class TravelExpensesCategory
{
public int ID { get; set; }
public string Name { get; set; }
}
}
差旅費用項目紀錄類別
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Models
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
TravelExpense
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
TravelExpense.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Models
{
public class TravelExpense
{
public int ID { get; set; }
public string Account { get; set; }
public DateTime TravelDate { get; set; }
public string Category { get; set; }
public string Title { get; set; }
public string Location { get; set; }
public double Expense { get; set; }
public string Memo { get; set; }
public bool Domestic { get; set; }
public bool HasDocument { get; set; }
public DateTime Updatetime { get; set; }
}
}
建立輔助支援類別
系統使用的資料
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Helps
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
AppData
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
AppData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using XFDoggy.Models;
using XFDoggy.Services;
namespace XFDoggy.Helps
{
public class AppData
{
public static string UserUrl { get; set; } = "http://xamarindoggy.azurewebsites.net/api/user";
public static string TravelExpensesCategoryUrl { get; set; } = "http://xamarindoggy.azurewebsites.net/api/TravelExpensesCategory";
public static string UserAuthUrl { get; set; } = "http://xamarindoggy.azurewebsites.net/api/User/Auth";
//public static string TravelExpenseGetUrl { get; set; } = "http://xamarindoggy.azurewebsites.net/api/TravelExpense?account=";
public static string TravelExpenseUrl { get; set; } = "http://xamarindoggy.azurewebsites.net/api/TravelExpense";
public static DataService DataService = new DataService();
public static List<TravelExpense> AllTravelExpense = new List<TravelExpense>();
public static List<TravelExpensesCategory> AllTravelExpensesCategory = new List<TravelExpensesCategory>();
public static string Account = "";
public static 執行功能列舉 正在執行功能 = 執行功能列舉.差旅費用申請;
}
public enum 執行功能列舉
{
差旅費用申請,
登出,
}
}
建立基礎服務與介面和實作
呼叫 Web API 的服務
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Services
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
DataService
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
DataService.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using XFDoggy.Helps;
using XFDoggy.Models;
namespace XFDoggy.Services
{
public class DataService
{
private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
private HttpClient GetClient()
{
HttpClient client = new HttpClient(new HttpClientHandler());
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
#region TravelExpense
public async Task<IEnumerable<TravelExpense>> GetTravelExpensesAsync(string account)
{
using (HttpClient client = GetClient())
{
var fooStr = $"{AppData.TravelExpenseUrl}?account={account}";
HttpResponseMessage httpResponseMessage = await client.GetAsync(fooStr);
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<IEnumerable<TravelExpense>>(content);
}
}
public async Task PostTravelExpensesAsync(TravelExpense travelExpense)
{
using (HttpClient client = GetClient())
{
HttpResponseMessage httpResponseMessage = await client.PostAsync(AppData.TravelExpenseUrl,
new StringContent(
JsonConvert.SerializeObject(travelExpense, _jsonSerializerSettings),
Encoding.UTF8, "application/json"));
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return;
}
}
public async Task PutTravelExpensesAsync(TravelExpense travelExpense)
{
using (HttpClient client = GetClient())
{
HttpResponseMessage httpResponseMessage = await client.PutAsync(AppData.TravelExpenseUrl,
new StringContent(
JsonConvert.SerializeObject(travelExpense, _jsonSerializerSettings),
Encoding.UTF8, "application/json"));
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return;
}
}
public async Task DeleteTravelExpensesAsync(int id)
{
using (HttpClient client = GetClient())
{
HttpResponseMessage httpResponseMessage = await client.DeleteAsync($"{AppData.TravelExpenseUrl}?id={id}");
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return;
}
}
#endregion
#region TravelExpensesCategory
public async Task<IEnumerable<TravelExpensesCategory>> GetTravelExpensesCategoryAsync()
{
using (HttpClient client = GetClient())
{
HttpResponseMessage httpResponseMessage = await client.GetAsync(AppData.TravelExpensesCategoryUrl);
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<IEnumerable<TravelExpensesCategory>>(content);
}
}
#endregion
#region User
public async Task<AuthUserResult> AuthUserAsync(AuthUser authUser)
{
using (HttpClient client = GetClient())
{
HttpResponseMessage httpResponseMessage = await client.PostAsync(AppData.UserAuthUrl,
new StringContent(
JsonConvert.SerializeObject(authUser, _jsonSerializerSettings),
Encoding.UTF8, "application/json"));
httpResponseMessage.EnsureSuccessStatusCode();
string content = await httpResponseMessage.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<AuthUserResult>(content);
}
}
#endregion
}
}
Prism 事件服務使用類別
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Infrastructure
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
CRUDEvent
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
CRUDEvent.cs
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Infrastructure
{
public class CRUDEvent : PubSubEvent<string>
{
}
}
取得是否在 Debug 除錯模式下的介面
- 在核心PCL
XFDoggy
專案內,使用滑鼠右鍵點選Infrastructure
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
IDebugMode
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
IDebugMode.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XFDoggy.Infrastructure
{
public interface IDebugMode
{
bool IsDebugMode();
}
}
Android 平台實作 是否在 Debug 除錯模式下 功能
- 在
XFDoggy.Droid
專案內,使用滑鼠右鍵點選Infrastructure
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>Class
- 在底下名稱欄位內,輸入
DebugMode
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
DebugMode.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using XFDoggy.Droid.Infrastructure;
using XFDoggy.Infrastructure;
[assembly: Xamarin.Forms.Dependency(typeof(DebugMode))]
namespace XFDoggy.Droid.Infrastructure
{
public class DebugMode : IDebugMode
{
public bool IsDebugMode()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
iOS 平台實作 是否在 Debug 除錯模式下 功能
- 在
XFDoggy.iOS
專案內,使用滑鼠右鍵點選Infrastructure
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Apple
>Class
- 在底下名稱欄位內,輸入
DebugMode
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
DebugMode.cs
using XFDoggy.Infrastructure;
using XFDoggy.iOS.Infrastructure;
[assembly: Xamarin.Forms.Dependency(typeof(DebugMode))]
namespace XFDoggy.iOS.Infrastructure
{
public class DebugMode : IDebugMode
{
public bool IsDebugMode()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
UWP 平台實作 是否在 Debug 除錯模式下 功能
- 在
XFDoggy.UWP
專案內,使用滑鼠右鍵點選Infrastructure
資料夾,接著,選擇加入
>類別
- 在
加入新項目 - XFDoggy
對話窗中,點選Visual C#
>類別
- 在底下名稱欄位內,輸入
DebugMode
,接著,點選新增
按鈕 - 使用底下程式碼替換掉剛剛產生的檔案內容
DebugMode.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XFDoggy.Infrastructure;
using XFDoggy.UWP.Infrastructure;
[assembly: Xamarin.Forms.Dependency(typeof(DebugMode))]
namespace XFDoggy.UWP.Infrastructure
{
class DebugMode : IDebugMode
{
public bool IsDebugMode()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
建立全域XAML樣式
修改 App.xaml 之 XAML 樣式定義
- 在核心PCL
XFDoggy
專案內,開啟App.xaml
檔案 - 使用底下 XAML 宣告標記替換掉剛剛開啟的檔案內容
DebugMode.cs
<?xml version="1.0" encoding="utf-8" ?>
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
x:Class="XFDoggy.App">
<Application.Resources>
<!-- Application resource dictionary -->
<ResourceDictionary>
<Color x:Key="PageBackgroundColor">#FFEFD4</Color>
<Color x:Key="ToolbarBackgroundColor">#f08915</Color>
<Color x:Key="BottomCommandBackgroundColor">#ffcc92</Color>
<Color x:Key="ButtonTextColor">#fff</Color>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>