.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N120212101
出刊日期:2012/02/01
本文延續《.Net Framework 4.5與Visual Studio 11 - WCF Web API (1)》一文的內容來探討WCF Web API提供的新功能,利用Visual Studio 11 Developer Preview開發工具來開發服務程式碼,讓你更容易設計支援REST類型的WCF服務。由於本文撰寫時使用的工具是Visual Studio 11 Developer Preview,而WCF Web API 則是Preview 6版,因此本文探討的內容在正式版上市時可能不適用。
延續前一篇文章《.Net Framework 4.5與Visual Studio 11 - WCF Web API (1)》的情境,介紹如何透過WCF Web API來提供新增、刪除、修改資料的功能。
定義介面
首先為WCF服務設計好用來新增、刪除以及修改資料所需的操作(Operation)。在IService.cs檔案中,為IService介面新增CreateEmployee、DeleteEmployee與UpdateEmployee三個方法定義,IService1介面的程式碼看起來如下:
namespace WCFWebLib
{
[ServiceContract]
public interface IService1
{
[WebGet ( UriTemplate = "/employees" )]
[OperationContract]
List<Employee> GetEmployees ( );
[WebGet ( UriTemplate = "/employees/{id}" )]
[OperationContract]
Employee GetEmployeeByID ( int id );
[WebInvoke ( UriTemplate = "/employees" , Method = "POST" )]
HttpResponseMessage<Employee>
CreateEmployee ( HttpRequestMessage<Employee> request);
[WebInvoke ( UriTemplate = "/employees/{id}" , Method = "DELETE" )]
Employee DeleteEmployee ( int id );
[WebInvoke ( UriTemplate = "/employees/{id}" , Method = "PUT" )]
Employee UpdateEmployee (Employee emp );
}
}
CreateEmployee、DeleteEmployee與UpdateEmployee方法上方套用了WebInvoke Attribute,並分別設定Method為POST、DELETE與PUT,以處理HTTP POST、DELETE與PUT請求,在這個範例中,分別以HTTP POST、DELETE與PUT請求來進行資料的新增、刪除與修改。
WCF Web API除了新增一個HTTPClient類別來傳送HTTP請求、接收HTTP回應之外,另設計了HTTPRequestMessage與HttpResponseMessage類別來代表HTTP請求與回應的訊息。
實作方法
定義好介面之後,接著在Service1類別中實作CreateEmployee、DeleteEmployee與UpdateEmployee三個方法,CreateEmployee方法的程式碼看起來如下:
public System.Net.Http.HttpResponseMessage<Employee>
CreateEmployee ( HttpRequestMessage<Employee> request )
{
HttpResponseMessage<Employee> response = null;
Employee emp = ( Employee ) request.Content.ReadAsAsync ( ).Result;
if ( emp == null )
{
response = new HttpResponseMessage<Employee> (
HttpStatusCode.BadRequest );
}
else
{
Store.Add (emp );
response = new HttpResponseMessage<Employee> (
emp , HttpStatusCode.Created );
response.Headers.Location = new Uri (
request.RequestUri , emp.EmployeeID.ToString ( ) );
}
return response;
}
範例中CreateEmployee方法用來新增資料,此方法將會回傳一個HttpResponseMessage<Employee>型別的物件,以便傳回執行結果,像是HTTP狀態碼等資訊。方法中先讀取HttpRequestMessage<Employee>訊息內文是否包含一個Employee物件,若沒有則回傳HTTP狀態碼 400 (HttpStatusCode.BadRequest列舉值)。若包含一個Employee物件,則回傳HTTP狀態碼201 (HttpStatusCode.Created列舉值),並利用HTTP Header傳回URI等資訊。
DeleteEmployee與UpdateEmployee方法雷同,先叫用GetEmployeeById方法來取得欲刪除與修改的Employee物件 ,若找不到時將丟出HttpResponseException例外錯誤,並傳回狀態碼。若找到欲刪除與修改的Employee物件再進行刪除或修改的動作。
public Employee DeleteEmployee ( int id )
{
Employee emp = Store.GetEmployeeById ( id );
if ( emp == null )
{
throw new HttpResponseException ( HttpStatusCode.NotFound );
}
Store.Delete ( emp );
return emp;
}
public Employee UpdateEmployee ( Employee emp )
{
var toUpdate = Store.GetEmployeeById ( emp.EmployeeID );
if ( toUpdate == null )
{
throw new HttpResponseException ( HttpStatusCode.NotFound );
}
Console.WriteLine ( "Service..." );
Console.WriteLine ("New Name:" + emp.EmployeeName );
Console.WriteLine ( "Original Name:" + toUpdate.EmployeeName );
toUpdate.EmployeeName = emp.EmployeeName;
return toUpdate;
}
更新資料用戶端程式
用戶端利用HttpClient類別的PutAsync方法執行呼叫,使用HTTP PUT動詞,利用非同步方式來進行資料的修改動作。在本文的範例中,想要修改1號員工的EmployeeName屬性,將其值設定為「New Mary」:
static void Main ( string [ ] args )
{
HttpClient client = new HttpClient ( );
client.BaseAddress = new Uri ( "http://localhost:8000/api/" );
Employee emp = new Employee ( ) { EmployeeID = 1 , EmployeeName = "New Mary" };
string id = "1";
var resp = client.PutAsync ( "employees/"+id ,
new ObjectContent<Employee> ( emp ,
XmlMediaTypeFormatter.DefaultMediaType ) )
.ContinueWith ( r =>
{
Console.WriteLine ( "Employee Updated..." );
Console.WriteLine ( r.Result.ToString ( ) );
r.Result.Content.ReadAsAsync<Employee> ( ).ContinueWith ( b =>
{
Employee e = b.Result;
Console.WriteLine ( "執行結果:");
Console.WriteLine ( "=========" );
Console.WriteLine ( "員工名稱:" + e.EmployeeName );
} );
} );
Console.WriteLine ( "Press [enter] to quit." );
Console.ReadLine ( );
}
此範例執行的結果請參考下圖所示,服務端程式執行結果:
圖 1:修改資料,服務端程式執行結果。
用戶端程式執行結果,請參考圖2所示:
圖 2:修改資料,用戶端程式執行結果。
刪除資料用戶端程式
刪除資料時,叫用的是HttpClient類別的DeleteAsync方法,以非同步方式進行刪除的作業。
static void Main ( string [ ] args )
{
HttpClient client = new HttpClient ( );
client.BaseAddress = new Uri ( "http://localhost:8000/api/" );
string id = "1";
var resp = client.DeleteAsync(String.Format ( "employees/{0}" , id ) );
Console.WriteLine ( resp.Result);
Console.WriteLine ( "Press [enter] to quit." );
Console.ReadLine ( );
}
刪除資料的範例用戶端執行結果如下圖所示:
圖 3:刪除資料,用戶端程式執行結果。
新增資料用戶端程式
若要新增資料,則使用HTTP POST動詞,利用HttpClient 類別PostAsync方法來進行:
static void Main ( string [ ] args )
{
HttpClient client = new HttpClient ( );
client.BaseAddress = new Uri ( "http://localhost:8000/api/" );
Employee emp = new Employee ( ) { EmployeeID = 4 , EmployeeName = "Landy" };
var resp = client.PostAsync ( "employees/" ,
new ObjectContent<Employee> ( emp ,
XmlMediaTypeFormatter.DefaultMediaType ) )
.ContinueWith ( r =>
{
Console.WriteLine ( "Employee Added..." );
Console.WriteLine ( r.Result.ToString ( ) );
} );
Console.WriteLine ( "Press [enter] to quit." );
Console.ReadLine ( );
}
用戶端執行結果,請參考圖4所示:
圖 4:新增資料,用戶端程式執行結果。
在ASP.NET裝載服務
若不想為WCF撰寫裝載程式,可以將WCF服務直接裝載在IIS上執行,本文最後介紹如何將使用 WCF Web API類型的服務裝載在ASP.NET類型的專案上。你可以在建立專案時,直接選擇使用Web應用程式,從Visual Studio 11 Developer Preview的「File」-「New」-「Project」,開啟「New Project」對話盒,然後選取程式語言,如Visual C#,再選擇「Web」-「ASP.NET MVC 4 Web Application」範本,取一個名字後按下「OK」按鈕建立專案,請參考圖5所示:
圖 5:建立「ASP.NET MVC 4 Web Application」專案。
接著會出現「New ASP.NET MVC 4 Project」對話盒,在這個範例中只需要建立Empty類型的範本即可,選取「Empty」範本之後,按下「OK」按鈕,請參考圖6所示:
圖 6:選取「Empty」範本。
和《.Net Framework 4.5與Visual Studio 11 - WCF Web API (1)》一文介紹的內容一樣,要先安裝NuGet Packages。在「Solution Explorer」視窗中選取你的專案,按滑鼠右鍵,從突顯式選單中,選取「Manage NuGet Packages」,請參考圖7所示:
圖 7:安裝NuGet Packages。
在「Manage NuGet Packages」對話盒Online選單中搜尋「WebApi.All」,然後按下「Install」按鈕,請參考圖8所示。
圖 8:安裝「WebApi.All」。
在專案中,新增一個Employee類別。從「Solution Explorer」視窗,選取專案,按滑鼠右鍵,從突顯式選單中,選取「Add」-「Class」,加入一個Employee類別,宣告類別中包含兩個屬性,分別是int型別的EmployeeID屬性,以及string型別的EmployeeName屬性:
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
}
按相同的方式新增EmployeeRepository類別:
public class EmployeeRepository
{
List<Employee> emps = new List<Employee> ( );
public EmployeeRepository ( )
{
Add ( new Employee ( ) { EmployeeID = 1 , EmployeeName = "Mary" } );
Add ( new Employee ( ) { EmployeeID = 2 , EmployeeName = "Candy" } );
Add ( new Employee ( ) { EmployeeID = 3 , EmployeeName = "Judy" } );
}
public void Add ( Employee emp )
{
emps.Add ( emp );
}
public void Delete ( Employee emp )
{
emps.Remove ( emp );
}
public List<Employee> GetEmployees ( )
{
return emps;
}
public Employee GetEmployeeById ( int id )
{
return emps.Find ( ( x ) => x.EmployeeID == id );
}
}
下一個步驟是新增一個EmployeeService類別來做為服務,您可以不必從定義介面開始,然後再實作介面。另外,在WCF Web API Preview 6版,宣告WCF Web API所需的類別上可以省略不用標識ServiceContract Attribute,服務的方法也不用標示OperationContract Attribute。但方法的上方要套用WebGet Attribute,並設定好UriTemplate將URL與方法對應在一起:
//[ServiceContract]
public class EmployeeService
{
static EmployeeRepository Store = new EmployeeRepository ( );
[WebGet ( UriTemplate = "/employees" )]
public List<Employee> GetEmployees ( )
{
return Store.GetEmployees ( );
}
}
專案中預設會包含一個Global.asax.cs檔案,在檔案的上方引用以下命名空間:
using Microsoft.ApplicationServer.Http.Activation;
using System.ServiceModel.Activation;
Global.asax.cs檔案中預設定義一個MvcApplication類別,在類別之中宣告一個HttpServiceHostFactory型別的變數:
static HttpServiceHostFactory _factory = null;
然後在Global.asax.cs檔案Application_Start方法中加入以下程式碼,這段程式碼的主要用途是將http://localhost:4462/api/employees
格式的URL對應到EmployeeService類別:
_factory = new HttpServiceHostFactory ( );
RouteTable.Routes.Add ( new ServiceRoute ( "api" , _factory , typeof ( EmployeeService ) ) );
完成這個動作之後,��可以進行測式。按F5執行網站,開啟瀏覽器,在URL上輸入 (注意localhost後方的埠號可能和您的專案不同):
http://localhost:4462/api/employees
網頁上便將查詢回來的Employee資料以XML方式呈現,請參考圖9所示:
圖 9:將查詢回來的Employee資料以XML方式呈現。
使用JavaScript與jQuery呼叫服務
在這個小節,我們將撰寫一個ASP.NET Web表單,以JavaScript和jQuery來呼叫服務。首先在專案中加一個Webform1.aspx,從「Solution Explorer」視窗,選取專案,按滑鼠右鍵,從突顯式選單中,選取「Add」-「New Item」,加入一個「Web Form」。
在Form標籤之中加入一個div,將id設定為emp:
<form id="form1" runat="server">
<div id="emp">
</div>
</form>
引用jquery函式庫,並撰寫以下JavaScript,在網頁載入時,叫用getJSON方法,取回所有員工資料,然後利用each方法,將EmployeeName顯示在li清單項目上:
<script src="Scripts/jquery-1.6.2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("api/employees",
function (data) {
$('#emp').empty();
$.each(data, function (key, val) {
$('<li/>', { html: val.EmployeeName })
.data({ employee: val })
.appendTo($('#emp'));
});
});
});
</script>
按F5執行網站,開啟瀏覽器,參考網頁執行結果:
圖 10:使用JavaScript與jQuery呼叫服務。
啟用WCF Web API Test Client
WCF Web API提供一個用戶端測試的工具程式,可以在開發階段讓程式設計師用來檢測服務的運行。若要使用這個工具程式來進行測試,您可以修改專案Application_Start方法如下,將HttpConfiguration類別的EnableTestClient屬性設定為true ,然後將HttpConfiguration設定給HttpServiceHostFactory的Configuration屬性,參考以下程式碼所示:
protected void Application_Start ( )
{
var config = new HttpConfiguration ( ) { EnableTestClient = true };
_factory = new HttpServiceHostFactory ( ) { Configuration = config };
RouteTable.Routes.Add ( new ServiceRoute ( "api" , _factory , typeof ( EmployeeService ) ) );
}
按F5執行網站,開啟瀏覽器,輸入以下URL:
http://localhost:4462/api/test/home
就可以看到WCF Web API Test Client的測試頁面了,請參考圖11所示。
圖 11:WCF Web API Test Client的測試頁面。
若服務不是裝載在IIS上執行,則裝載程式啟動前可以加入以下程式碼,利用HttpConfiguration類別啟用Test Client:
var config = new HttpConfiguration ( ) { EnableTestClient = true };
var host = new HttpServiceHost (
typeof ( Service1 ) ,config, "http://localhost:8000/api/" );
host.Open ( );
Console.WriteLine ( "Service is running..." );
Console.ReadLine ( );