使用 OData 動作實作伺服器端行為

Open Data Protocol (OData) 可讓您定義資料服務上的「服務動作」(Service Action)。 服務動作是定義在資料服務上的一種特殊作業。 服務動作提供一種方式,可將行為插入其他情況下以資料為中心的模型內。 服務動作可讓您在 OData 中叫用商務邏輯,其中的邏輯必須繫結至給定的資源。 服務動作與一般端點型服務作業的差異處如下:

  • 繫結至資源

    服務動作通常會繫結至資源、實體集 (摘要) 或個別實體,與固定端點上所定義的服務作業不同。 這些資源稱為「繫結參數」(Binding Parameter)。 在 WCF Data Services 中,繫結參數只能為實體類型和實體類型集合。 也可以提供非繫結參數給服務動作。 但是,這些參數只能為基本類型、複雜類型,或是基本或複雜類型的集合。 當服務動作繫結至資源時,此服務動作會在實體序列化中公開為動作資源。

  • 有副作用

    服務動作所叫用的商務邏輯會影響系統,例如變更資料或狀態或是叫用某個其他商務程序。 因為服務動作一定會有副作用,所以只能使用 POST 要求加以叫用。 與服務作業不同的是,非繫結參數會在主體訊息 (而不是 URI) 中提供給服務動作。 這些非繫結參數會在要求的主體中以 JavaScript 標記法 (JSON) 編碼值的形式提供。

  • 無法進一步組成

    服務動作可以擁有與服務作業相同的傳回類型。 但是,動作將無法進一步組成,這一點與服務作業不同。 這表示,系統查詢選項無法提供給服務動作。

將數位影片視為資源時,您可以對數位影片進行許多動作:簽出、評比/加註或簽入。 這些是管理數位影片之 WCF 資料服務可實作的所有動作範例。 動作描述於 OData 回應中,而這個回應包含可叫用動作的資源。 當使用者要求代表數位影片的資源時,從 WCF 資料服務傳回的回應就會包含可用於該項資源之動作的相關資訊。 動作的可用性可能會取決於資料服務或資源的狀態。 例如,一旦數位影片已簽出之後,就無法由其他使用者簽出。 用戶端只要指定 URL,就可以叫用動作。 例如,http://MyServer/MovieService.svc/Movies(6) 會識別特定的數位影片,而 http://MyServer/MovieService.svc/Movies(6)/Checkout 會針對特定的影片叫用動作。 動作可讓您公開服務模型,而不公開資料模型。 繼續處理影片服務範例時,您可能會想要讓使用者評比影片,但不直接以資源的形式公開評比資料。 此時,您可以實作評比動作,讓使用者評比影片,但不直接以資源的形式存取評比資料。

實作動作

若要實作服務動作,您必須實作 IServiceProviderIDataServiceActionProviderIDataServiceInvokable 介面。 IServiceProvider 可讓 WCF Data Services 取得您的 IDataServiceActionProvider 實作。 IDataServiceActionProvider 可讓 WCF Data Services 建立、尋找、描述和叫用服務動作。 IDataServiceInvokable 可讓您叫用實作服務動作之行為的程式碼,並且取得結果 (如果有的話)。 請記住,WCF Data Services 是每次呼叫的 WCF 服務,亦即每次呼叫服務時,都會建立新的服務執行個體。 請確定建立服務時,不會進行任何不必要的工作。

IServiceProvider

IServiceProvider 包含名為 GetService(Type) 的方法。 WCF Data Services 會呼叫此方法來擷取許多服務提供者,包括中繼資料服務提供者和資料服務動作提供者。 當系統要求提供資料服務動作提供者時,請傳回您的 IDataServiceActionProvider 實作。

IDataServiceActionProvider

IDataServiceActionProvider 包含一些方法,可讓您擷取可用動作的相關資訊。 當您實作 IDataServiceActionProvider 時,就會使用動作來擴充服務之 IDataServiceMetadataProvider 實作所定義的服務中繼資料,並且適當地處理這些動作的分派。

AdvertiseServiceAction

呼叫 AdvertiseServiceAction(DataServiceOperationContext, ServiceAction, Object, Boolean, ODataAction%) 的目的是要判斷哪些動作可用於指定的資源。 這個方法只會針對非永遠可用的動作呼叫。 它是用來根據所要求之資源的狀態或服務的狀態,檢查動作是否應該包含在 OData 回應中。 這項檢查的完成方式完全由您自行決定。 如果計算可用性相當耗費資源,而且目前資源位於摘要中,則略過檢查並通告動作就是可接受的作法。 如果目前傳回的資源屬於摘要的一部分,inFeed 參數就會設定為 true。

CreateInvokable

呼叫 CreateInvokable(DataServiceOperationContext, ServiceAction, array<Object[]) 的目的是要建立包含委派的 IDataServiceInvokable,這個委派會封裝實作動作之行為的程式碼。 這樣會建立 IDataServiceInvokable 執行個體,但是不會叫用動作。 WCF 資料服務動作有副作用,而且必須搭配更新提供者運作,才能將這些變更儲存至磁碟。 呼叫 Invoke() 方法是因為呼叫了更新提供者的 SaveChanges() 方法。

GetServiceActions

這個方法會傳回 ServiceAction 執行個體的集合,這些執行個體代表 WCF 資料服務公開的所有動作。 ServiceAction 是動作的中繼資料表示,其中包括動作名稱、參數和傳回類型等資訊。

GetServiceActionsByBindingParameterType

這個方法會傳回所有可繫結至指定繫結參數類型之 ServiceAction 執行個體的集合。 也就是說,所有可針對指定之資源類型 (也稱為繫結參數類型) 執行的 ServiceAction。這個方法是在服務傳回資源時使用,以便加入可針對該項資源叫用之動作的相關資訊。 這個方法應該只會傳回可繫結至確切繫結參數類型 (無衍生類型) 的動作。 這個方法是在遇到每種類型時,針對每個要求呼叫一次,而且結果由 WCF Data Services 進行快取。

TryResolveServiceAction

這個方法會搜尋指定的 ServiceAction,而且如果找到 ServiceAction,就會傳回 true。 如果有找到,就會在 serviceAction out 參數中傳回 ServiceAction

IDataServiceInvokable

這個介面會提供一種執行 WCF 資料服務動作的方式。 實作 IDataServiceInvokable 時,您必須負責處理 3 件事:

  1. 擷取參數,而且可能要封送處理

  2. 將參數分派給呼叫 Invoke() 時實際實作動作的程式碼

  3. 儲存來自 Invoke() 的任何結果,以便使用 GetResult() 來擷取這些結果

參數可能會以 Token 的形式傳遞。 這是因為您可以寫入使用代表資源之 Token 的資料服務提供者,如果是這種情況,您可能必須先將這些 Token 轉換 (封送處理) 成實際資源,然後再分派給實際動作。 封送處理參數之後,它必須處於可編輯狀態,如此一來,叫用動作時對資源進行的任何變更才會儲存並寫入磁碟。

這個介面需要兩個方法:Invoke 和 GetResult。 Invoke 會叫用實作動作之行為的委派,而 GetResult 會傳回動作的結果。

服務動作存取控制

在 WCF Data Services 中,服務動作的服務範圍可視性是由 IDataServiceConfiguration 類別上的 SetServiceActionAccessRule(String, ServiceActionRights) 方法所控制,與使用 SetServiceOperationAccessRule(String, ServiceOperationRights) 方法控制服務作業可視性的方式相同。

服務動作的中繼資料定義

就像服務作業一樣,服務動作會在服務中繼資料中定義為 FunctionImport 元素。 服務動作 FunctionImport 包含零個或多個 Parameter 元素,這些元素同時代表繫結參數和非繫結參數。 此外,FunctionImport 上的以下屬性會定義服務動作的行為:

  • IsSideEffecting

    因為服務動作一定會有副作用,所以這個屬性一定會是 true。

  • IsBindable

    服務動作通常會繫結至資源,但不是絕對。 當這個屬性為 true 時,第一個參數必須為實體類型或實體集合。

  • IsComposable

    因為服務動作不支援其他查詢撰寫,所以這個屬性一定會是 false。

叫用 WCF 資料服務動作

動作是使用 HTTP POST 要求來叫用的。 URL 會依序指定資源和動作名稱。 參數是透過要求的主體傳遞的。 例如,假設有一項名為 MovieService 的服務,而這項服務公開了名為 Rate 的動作。 您就可以使用下列 URL,針對特定的影片叫用 Rate 動作:

http://MovieServer/MovieService.svc/Movies(1)/Rate

Movies(1) 會指定您想要評比的影片,而 Rate 會指定評比動作。 評比的實際值將位於 HTTP 要求的主體中,如下列範例所示:

POST http://MovieServer/MoviesService.svc/Movies(1)/Rate HTTP/1.1 
Content-Type: application/json 
Content-Length: 20 
Host: localhost:15238
{ 
   "rating": 4 
}

注意

上述範例程式碼只能搭配支援 JSON Light 的 WCF Data Services 5.2 和更新版本運作。如果使用舊版 WCF Data Services,您就必須依照下列方式指定 Json 詳細資訊內容類型:application/json;odata=verbose。

或者,您也可以使用 WCF Data Services 用戶端來叫用動作,如下列程式碼片段所示。

MoviesModel context = new MoviesModel (new Uri("http://MyServer/MoviesService.svc/"));
            //...
            context.Execute(new Uri("http://MyServer/MoviesService.svc/Movies(1)/Rate"), "POST", new BodyOperationParameter("rating",4) );         

在上述程式碼片段中,MoviesModel 類別的產生方式是使用 Visual Studio,加入 WCF 資料服務的服務參考。

請參閱

概念

開發和部署 WCF Data Services

自訂資料服務提供者 (WCF Data Services)

其他資源

WCF Data Services

資料服務 (WCF Data Services)