建立 Silverlight 應用程式 (WCF Data Services)
重要
Windows Phone 應用程式不支援適用於 Silverlight 的 WCF Data Services 5.0 用戶端程式庫。您必須改用適用於 Windows Phone 的 OData 用戶端程式庫 (包含在 Windows Phone 7.1 SDK 中)。如需詳細資訊,請參閱適用於 Windows Phone 的開放式資料通訊協定 (OData) 概觀。目前沒有支援 OData v3 的 Windows Phone 用戶端程式庫。
Silverlight 適用的 WCF Data Services 用戶端程式庫會產生資料服務的 HTTP 要求,該資料服務可支援版本 3 的 OData 通訊協定,並將 OData 回應摘要中的資料轉換為用戶端的物件。 用戶端程式庫的兩個主要類別是 DataServiceContext 類別和 DataServiceQuery<TElement> 類別。 DataServiceContext 類別會封裝針對指定之資料服務執行的作業。 OData 架構的服務沒有狀態。 但是,DataServiceContext 會在用戶端維護與資料服務互動之間的實體狀態。 如此可讓用戶端支援類似變更追蹤和識別管理的功能。 DataServiceQuery<TElement> 類別表示針對特定實體集的查詢。 如需詳細資訊,請參閱使用 .NET Framework 應用程式中的資料服務 (WCF Data Services)。 如需從 Northwind 範例資料服務取用摘要的即時應用程式範例,請參閱適用於 Silverlight 的 WCF Data Services 快速入門。
注意
使用適用於 Silverlight 的 WCF Data Services 用戶端程式庫時,將會以非同步方式發出服務的所有要求。如需詳細資訊,請參閱非同步作業 (WCF Data Services)。
此主題包括下列章節:
產生用戶端資料服務類別
您可以使用 Visual Studio 中的 [加入服務參考] 對話方塊,加入可公開 OData 摘要之任何服務的參考。 如需詳細資訊,請參閱產生用戶端資料服務類別 (WCF Data Services)。 您也可以在命令提示字元中使用 DataSvcUtil.exe 工具,產生用戶端資料服務類別。 如需詳細資訊,請參閱 HOW TO:手動產生用戶端資料服務類別 (WCF Data Services)。
注意
安裝 WCF Data Services 5.0 版本之後,[加入服務參考] 工具將會自動加入 Microsoft.Data.Services.Client.SL.dll 版本之用戶端程式庫的參考,而不是加入 Silverlight 中所包含之 System.Data.Services.Client.dll 版本的參考。如果您因為某個原因需要改用舊版的 Silverlight 用戶端,您應該手動加入 Silverlight 版本之用戶端程式庫的參考。如需詳細資訊,請參閱 HOW TO:手動產生用戶端資料服務類別 (WCF Data Services)。
存取和變更資源
在 Silverlight 架構的應用程式中,針對資料服務進行的所有作業都是非同步的。 您可以針對分別從 Begin 和 End 開始的 DataServiceContext 與 DataServiceQuery<TElement> 類別使用方法配對來執行非同步作業。 作業完成時,Begin 方法會註冊服務呼叫的委派。 在註冊的委派中應該呼叫 End 方法,以處理來自已完成作業的回呼。 當您呼叫 End 方法來完成非同步作業時,必須從您用來開始作業的相同 DataServiceQuery<TElement> 或 DataServiceContext 執行個體進行。 每個 Begin 方法都會採用 state 參數,這個參數可以將狀態物件傳遞至回呼。 這個狀態物件會以與回呼一起提供的 IAsyncResult 形式擷取,且用於呼叫對應的 End 方法來完成非同步作業。 例如,如果您在 DataServiceQuery<TElement> 執行個體上呼叫 BeginExecute 方法時,提供此執行個體做為 state 參數,便會傳回相同的 DataServiceQuery<TElement> 執行個體當做 IAsyncResult。 接著會使用這個 DataServiceQuery<TElement> 執行個體呼叫 EndExecute 方法,以完成查詢作業。 如需詳細資訊,請參閱非同步作業 (WCF Data Services)。
因為適用於 Silverlight 的 WCF Data Services 用戶端程式庫會使用網路通訊協定來以非同步方式存取資料服務,所以您必須使用 Dispatcher 類別的 BeginInvoke 方法,將回應作業正確封送處理回 Silverlight 架構應用程式的主應用程式執行緒 (UI 執行緒)。 如需詳細資訊,請參閱Synchronizing Data for Multithreading。
查詢資源
適用於 Silverlight 的 WCF Data Services 用戶端程式庫可讓您使用熟悉的 .NET Framework 程式設計模式 (包括使用 Language Integrated Query (LINQ)) 針對 OData 資料服務執行查詢。 當呼叫 DataServiceQuery<TElement> 或 DataServiceContext 上的 BeginExecute 方法時,用戶端程式庫會將查詢或統一資源識別元 (URI) 轉譯為 HTTP GET 要求訊息。 用戶端程式庫會接收對應的回應訊息,並將它轉譯為用戶端資料服務類別的執行個體。 這些類別會由 DataServiceQuery<TElement> 所屬的 DataServiceContext 追蹤。 如需詳細資訊,請參閱 HOW TO:執行非同步資料服務查詢 (WCF Data Services)。
在部分情況下,這麼做有助於得知實體集中的實體總數,而不僅是摘要中查詢傳回的數目。 在 DataServiceQuery<TElement> 上呼叫 IncludeTotalCount 方法,以要求集合中的這項實體總計數包含在查詢結果中。 在此案例中,傳回之 QueryOperationResponse<T> 的 TotalCount 屬性會傳回集合中的實體總數。 您也可以使用 AddQueryOption 方法,將 OData 支援的任何其他查詢選項加入至查詢中。 如需詳細資訊,請參閱查詢資料服務 (WCF Data Services)。
LINQ 查詢
因為 DataServiceQuery<TElement> 類別會實作由 LINQ 定義的 IQueryable<T> 介面,因此適用於 Silverlight 的 WCF Data Services 用戶端程式庫可將針對實體集資料的 LINQ 查詢轉換為 URI (代表針對資料服務資源評估的查詢運算式)。 例如,以下 LINQ 查詢會傳回摘要,此摘要是以 CustomerID 屬性值篩選的 Order 實體集合 (該屬性值是由使用者在 customerId 文字方塊中所提供)。
' Define a query that returns orders for a give customer.
Dim query = From orderByCustomer In context.Orders _
Where orderByCustomer.Customer.CustomerID = _
Me.customerId.Text _
Select orderByCustomer
// Define a query that returns orders for a give customer.
var query = from orderByCustomer in context.Orders
where orderByCustomer.Customer.CustomerID == this.customerId.Text
select orderByCustomer;
載入延後的內容
根據預設,WCF Data Services 會限制查詢傳回的資料量。 不過,您可以在需要時,從資料服務明確載入其他資料,包括相關實體、分頁回應資料以及二進位資料流。 執行查詢時,只會傳回已定址之實體集中的實體。 例如,針對 Northwind 資料服務的查詢傳回 Customers 實體時,即使 Customers 和 Orders 之間有關聯性,預設仍不會傳回相關的 Orders 實體。 相關實體可以與原始查詢一起載入 (積極式載入),或是以各個實體的方式載入 (明確式載入)。 如需詳細資訊,請參閱載入延後的內容 (WCF Data Services)。 當使用 Silverlight 用戶端和 DataServiceCollection<T> 時,您可以藉由呼叫 LoadAsync 來從導覽屬性載入相關實體集合。
提示
當您決定要使用哪一種模式來載入相關實體時,請考量訊息大小與資料服務要求數目之間必須有效能上的取捨。
在資料服務中啟用分頁時,您必須在傳回的項目數超出分頁限制時,從資料服務明確地載入後續的資料頁。 因為無法事先判斷何時會發生分頁,所以我們建議您啟用 Silverlight 用戶端應用程式,以便適當地處理分頁 OData 摘要。 如需如何處理分頁回應的範例,請參閱 HOW TO:將資料服務資料繫結至控制項 (Silverlight 用戶端) 和查詢資料服務 (WCF Data Services)。
查詢投影
投影提供一種機制,可藉由指定回應中僅傳回特定實體屬性的方式,減少查詢傳回之 OData 摘要中的資料量。 如需詳細資訊,請參閱 OData:Select 系統查詢選項 ($select)。 您可以使用 select 子句 (Visual Basic 中則使用 Select),將投影子句加入至 LINQ 查詢中。 傳回的實體資料可以投影至用戶端上的實體類型或非實體類型。 對非實體類型所做的變更將無法儲存至資料服務。 例如,以下 LINQ 查詢會將 Customer 資料投影至用戶端的新 CustomerAddress 實體類型。
Dim query = From c In context.Customers _
Where c.Country = "Germany" _
Select New CustomerAddress With
{.CustomerID = c.CustomerID, _
.Address = c.Address, _
.City = c.City, _
.PostalCode = c.PostalCode, _
.Country = c.Country _
}
var query = from c in context.Customers
where c.Country == "Germany"
select new CustomerAddress
{
CustomerID = c.CustomerID,
Address = c.Address,
City = c.City,
PostalCode = c.PostalCode,
Country = c.Country
};
重要
當您儲存對投影類型所進行的更新時,資料服務中可能會遺失資料。如需詳細資訊,請參閱 WCF Data Services 用戶端文件中的投影考量因素。
如需詳細資訊,請參閱 HOW TO:專案資料服務查詢結果 (Silverlight 用戶端)。
修改資源及儲存變更
用戶端會追蹤您在 DataServiceContext 上手動執行以下方法所報告之實體的變更:
這些方法會讓用戶端追蹤所新增及刪除的實體,以及您對屬性值所做的變更或是您對實體執行個體之間的關聯性所做的變更。 當您使用 [加入服務參考] 對話方塊產生用戶端資料服務類別時,也會針對產生之 DataServiceContext 類別中的每一個實體建立 AddTo 方法。 使用這些方法可將新的實體執行個體加入至實體集,並報告內容所新增的項目。 當您呼叫 BeginSaveChanges 和 EndSaveChanges 方法時,這些追蹤的變更會以非同步方式傳回資料服務。
當您使用 AddObject 方法或是適當的 AddTo 方法加入新實體時,將不會自動定義新實體與相關實體之間的任何關聯性。 您可以建立和變更實體執行個體之間的關聯性,而且可以讓用戶端程式庫在資料服務中反映那些變更。 實體之間的關聯性會定義為模型中的關聯,而且 DataServiceContext 會追蹤每一個關聯性,如同內容中的連結物件。 WCF Data Services 可在 DataServiceContext 類別上,提供下列方法建立、修改及刪除這些連結:
如需詳細資訊,請參閱更新資料服務 (WCF Data Services)。
使用二進位資料
OData 會定義一種機制來存取二進位資料,與它所屬的實體區隔開來。 在這個方式之下,OData 服務可以將大型二進位資料公開為屬於媒體連結項目的媒體資源。 適用於 Silverlight 的 WCF Data Services 用戶端可以從 OData 服務取用媒體資源當做二進位資料流。 若要存取二進位資料流,請在追蹤媒體連結項目之實體的 DataServiceContext 執行個體上呼叫 BeginGetReadStream 方法。 在回呼所傳回的 DataServiceContext 執行個體上呼叫 EndGetReadStream 方法時,這個非同步方法會傳回 DataServiceStreamResponse 物件。 同樣地,當您呼叫 SetSaveStream 方法時以及呼叫 BeginSaveChanges 和 EndSaveChanges 方法之後,媒體資源會傳回 OData 服務。 如需詳細資訊,請參閱 HOW TO:以資料流形式存取二進位資料 (Silverlight 用戶端)。
資料繫結
適用於 Silverlight 的 WCF Data Services 用戶端可藉由使用 DataServiceCollection<T> 類別來支援將資料繫結至控制項。 繼承自 ObservableCollection<T> 的這個類別表示從集合中新增或移除項目時,提供通知的動態資料集合。 這些通知可讓 DataServiceContext 自動追蹤變更,您不必明確呼叫變更追蹤方法。 DataServiceCollection<T> 是根據 DataServiceQuery<TElement> 所定義。 當執行這個查詢時,將會提供集合的物件。
LoadAsync 方法是用來以非同步方式執行查詢,並將結果載入至集合。 這個方法會確保結果可封送處理至正確的執行緒,好讓您不需要使用 Dispatcher。 當您使用 DataServiceCollection<T> 的執行個體進行資料繫結時,用戶端會確保 DataServiceContext 所追蹤的物件與繫結 UI 元素中的資料保持同步。 您不需要將繫結集合中實體的變更手動提報給 DataServiceContext。 如需詳細資訊,請參閱 HOW TO:將資料服務資料繫結至控制項 (Silverlight 用戶端)。
跨網域執行
Silverlight 可讓您存取個別網域中所裝載的服務。 您必須在伺服器上部署跨網域原則檔案來明確啟用這種類型的存取。 這個功能包含在 Silverlight 用戶端 HTTP 實作中。
注意
在您允許 Silverlight 用戶端於跨網域情況下存取 Web 服務之前,必須考量一些重要的安全事項。如需詳細資訊,請參閱 HTTP Communication and Security with Silverlight。
對於資料服務的大多數要求而言,適用於 Silverlight 的 WCF Data Services 用戶端會使用 XMLHTTP 實作。 但是,當 WCF Data Services 用戶端偵測到跨網域要求時,它會自動切換成使用 Silverlight 用戶端 HTTP 實作。
如需如何設定資料服務來允許 Silverlight 架構應用程式中之跨網域要求的範例,請參閱在 X 網域和瀏覽器外用情況下使用 ADO.NET Data Services Silverlight 用戶端文章。 跨網域執行的支援是 Silverlight 4 中所新增的功能。
瀏覽器外用執行
您可以設定 Silverlight 架構應用程式,好讓使用者可以從他們的主機網頁安裝這些應用程式,並從瀏覽器外執行。 適用於 Silverlight 的 WCF Data Services 用戶端支援瀏覽器外用執行。 當 WCF Data Services 用戶端偵測到應用程式從瀏覽器外執行時,它會自動切換成使用 Silverlight 用戶端 HTTP 實作。 這與跨網域執行時所發生的行為相同,但是不需要跨網域原則檔案。 如需詳細資訊,請參閱Out-of-Browser Support。
用戶端驗證
根據預設,適用於 Silverlight 的 WCF Data Services 用戶端會使用與 Web 瀏覽器相同的用戶端認證來對資料服務提出要求,而且驗證是由 Web 瀏覽器所管理。 但是,當存取資料服務需要跨網域要求或是 Silverlight 應用程式從 Web 瀏覽器外執行時,您能夠指定提出要求時所提供的認證。 在這些情況下,用戶端會自動使用 Silverlight 用戶端 HTTP 實作來提出要求,而且會在驗證時使用預設認證。 但是,當 UseDefaultCredentials 屬性設定為 false 時,用戶端向資料服務驗證時會使用指派給 Credentials 屬性的 ICredentials。
注意
使用者認證只有在執行期間才會要求,而且不得快取。認證永遠必須以安全的方式儲存。
您也可以要求應用程式使用 Silverlight 用戶端 HTTP 實作來提供認證。 若要這樣做,您必須將 HttpStack 屬性的值設定為 ClientHttp。 以下程式碼確保在存取資料服務時,將會使用執行期間向使用者收集而來的認證:
' Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp
context.UseDefaultCredentials = False
context.Credentials = _
New NetworkCredential(userName, password, domain)
// Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp;
context.UseDefaultCredentials = false;
context.Credentials =
new NetworkCredential(userName, password, domain);
如果不使用 Silverlight 用戶端 HTTP 實作,將 UseDefaultCredentials 屬性的值設定為 false 會導致執行期間引發例外狀況。 當 UseDefaultCredentials 的值為 true 時,即使有設定 Credentials 屬性還是會使用預設認證。
注意
使用基本與摘要式驗證傳送的資料不會經過加密,因此敵人可以看到資料。此外,基本驗證認證 (使用者名稱和密碼) 會以純文字傳送,而且可以被攔截。
如需詳細資訊,請參閱 HOW TO:指定資料服務要求的用戶端認證 (Silverlight 用戶端)。 如需如何存取資料服務來使用 Silverlight 應用程式中之 ASP.NET 表單驗證的範例,請參閱在 X 網域和瀏覽器外用情況下使用 ADO.NET Data Services Silverlight 用戶端程式庫 – II (表單驗證) 文章。