摘要:ASP.NET Web API - Part 2. 實作 CRUD
範例的前置作業
首先開啟 SQL Server Management Studio,至於資料庫伺服器你可以使用 SQL Server 2005、2008 或 2008 R2。在你的 Local 資料庫伺服器上,建置新的資料庫。
資料庫名稱 MVCWebAPIDb,剩下都預設值即可。然後按確認。
在 MVCWebAPIDb 的資料庫上,建立新的資料表。
Table 的結構如下
|
名稱 |
資料類型 |
允許Nulls |
備註 |
|
SerialNo |
int |
不可 |
識別規格為識別 (是), 識別值種子 (1), 識別值增量(1). 然後設為主索引鍵 |
|
Name |
nvarchar(50) |
可 |
|
|
Message |
nvarchar(300) |
可 |
|
|
CreateDateTime |
Datetime |
可 |
|
儲存資料表 為 TBL_Message
儲存資料表 為 TBL_Message
點TBL_Message,右鍵開啟 編輯前200筆。
請加入 2- 5 筆資料或著可用以下的 Insert Script。
Use WebAPIDb
INSERT INTO TBL_Message(Name, Message, CreateDateTime)VALUES('Test1', 'Hello from Test1', GETDATE());
INSERT INTO TBL_Message(Name, Message, CreateDateTime)VALUES('Test2', 'Hello from Test2', GETDATE());
INSERT INTO TBL_Message(Name, Message, CreateDateTime)VALUES('Test3', 'Hello from Test3', GETDATE());
建置一個 Web API 支持 CRUD 操作
這個範例是講解如何使用 ASP.NET Web API 的 HTTP Service 來支援 CRUD操作。
CRUD 是 Create ,Read,Update,Delete 的縮寫。
GET 從定義的URI取得物件, 而 GET 應該不會造成物件的變動。
PUT 在指定的URI更新物件。如果服務器允許客戶指定新的客製URI,也可以在在指定的客製URI創建一個新的物件。
POST 創建一個新的物件, 服務器會用指定的URI來建立一個新的物件, 然後再用這指定的URI 回傳響應的訊息。
DELETE 用指定的URI來刪除物件。
備註: PUT 可以回傳更新好的物件, 也可以回傳響應的訊息. 如果是回傳更新好的物件,那客戶端就可以用回傳更新的物件做更新, 不然就是響應的訊息是成功時, 那客戶端就依照使用者輸入的資料自行更新
CRUD 本身也是資料庫的四大基本操作,很多HTTP Service 都使用 REST 或 REST-like APIs 來做CRUD操作。
我會建一個簡單的 Web API 來管理之前建的資料表 TBL_Message。
首先要建一個 MessageController,而這 Controller 會有以下 Action。
|
Action |
HTTP Method (Verb) |
URI |
|
取得所有訊息 |
GET |
/api/messages |
|
從ID取得訊息 |
GET |
/api/messages/id |
|
建立新訊息 |
POST |
/api/message |
|
更新訊息 |
PUT |
/api/message/id |
|
刪除訊息 |
DELETE |
/api/message/id |
|
|
|
|
所以如果我們要找 SerialNo = 3 的message,我們就要帶 http://hostname/api/messages/3
建立一個新的 ASP.NET Empty Web Applicaiton 專案
打開 Visual Studio 20102,從File 菜單選取 New 然後 Project 。
展開 Visual C#,在template 的清單上 選取 Web,然和在 project templates 選取 ASP.NET Empty Web Application,名稱設為 MvcCRUDSample,然後按 OK 。
備註: 在這裡我們選擇了 ASP.NET Empty Web Page 而不是 MVC 4 Web Application,我將會一步一步介紹如何使用 ASP.NET Web API 在一般的 ASP.NET Web Page 。我也讓讀者知道 ASP.NET Web API 雖然和 ASP.NET MVC 4 產品一起,但不是一定要用 ASP.NET MVC 4 才可使用 ASP.NET Web API 。
建立 ADO.NET Entity Data Model
選擇 MvcCRUDSample 專案, 按右鍵 選擇New,然後 New Item 。展開 Visual C#,在template 的清單上 選取 Data,然後在 左邊Panel 選取 ADO.NET Empty Model 名稱設為 MessageModel.edmx,然後按 OK 。
在Entity Data Model Wizard 視窗,選擇 Generate from database,然後按下一步。
選擇你當初建置的資料庫連線 然後按下一步。
在 Entity Data Model Wizard 視窗, 展開 Tables,勾選 TBL_Message 然後按結束。
新增 Web API Controller
這時我們就可以在 Web Applicaiton 上新增 Web API Controller。選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 New Item。
展開 Visual C# ,在template 的清單上 選取 Web,然和在 右邊Panel 選取 Web API Controller Class 名稱設為 MessageController,然後按 Add。
新增 Model
在應用程式裏,Model 是代表 資料的物件。在 ASP.NET Web API 裏,你可以(strongly typed) 強類型 Model,這樣在程式處理上會較為方便。而 ASP.NET Web API 會自動幫你 Model (serialized) 序列化 成 XML 或 JSON 給客戶端。
回到 MvcCRUDSample,選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 Class。名稱 MessageContext.cs。
在 MessageContext.cs 裏建置屬性。
public class MessageContext
{
public int SerialNo { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public string CreateDateTime { get; set; }
}
新增 Repository
在程式架構上,把服務層和群組物件隔開是個常用的方式,這樣子可以方便我們改變群組物件而不影響服務層。而這種設計就是叫 Repository pattern。
先來定義 Repository 的 interface。選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 New Item。展開 Visual C#,在template 的清單上 選取 Code,然後在 左邊Panel 選取 Interface 名稱設為 IMessageRepository,然後按 Add。
新增程式如下
public interface IMessageRepository
{
IEnumerable GetAll();
MessageContext Get(int SerialNo);
MessageContext Add(MessageContext msg);
MessageContext Remove(int SerialNo);
bool Update(MessageContext msg);
}
選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後新增一個 class,名稱為 MessageRepository。
而這 class 將繼承 IMessageRepository.
public class MessageRepository : IMessageRepository
{
public IEnumerable GetAll()
{
List messages = new List();
using (WebAPIDbEntities db = new WebAPIDbEntities())
{
Array.ForEach(db.TBL_Message.OrderBy(m => m.CreateDateTime).ToArray(),
m => messages.Add(new MessageContext { SerialNo = m.SerialNo, Name = m.Name, Message = m.Message, CreateDateTime = m.CreateDateTime.Value.ToString("yyyy/MM/dd HH:mm:ss") }));
}
return messages.AsEnumerable();
}
public MessageContext Get(int SerialNo)
{
MessageContext message = GetAll().Where(m => m.SerialNo == SerialNo).FirstOrDefault();
return message;
}
public MessageContext Add(MessageContext msg)
{
TBL_Message message = new TBL_Message { Name = msg.Name, Message = msg.Message, CreateDateTime = DateTime.Now };
using (WebAPIDbEntities db = new WebAPIDbEntities())
{
db.TBL_Message.Add(message);
db.SaveChanges();
msg = new MessageContext { Message = message.Message, Name = message.Name, CreateDateTime = message.CreateDateTime.Value.ToString("yyyy/MM/dd HH:mm:ss"), SerialNo = message.SerialNo };
}
return msg;
}
public MessageContext Remove(int SerialNo)
{
MessageContext message;
using (WebAPIDbEntities db = new WebAPIDbEntities())
{
TBL_Message m = db.TBL_Message.Where(c => c.SerialNo == SerialNo).FirstOrDefault();
if (m == null)
{
return null;
}
else
{
message = new MessageContext { SerialNo = m.SerialNo, CreateDateTime = m.CreateDateTime.Value.ToString("yyyy/MM/dd HH:mm:ss"), Name = m.Name, Message = m.Message };
db.TBL_Message.Remove(m);
db.SaveChanges();
}
}
return message;
}
public bool Update(MessageContext msg)
{
bool blResult = false;
using (WebAPIDbEntities db = new WebAPIDbEntities())
{
TBL_Message m = db.TBL_Message.Where(c => c.SerialNo == msg.SerialNo).FirstOrDefault();
if (m == null)
{
return blResult;
}
else
{
m.Message = msg.Message;
db.SaveChanges();
blResult = true;
}
}
return true;
}
}
實作MessageController
先啟用 MessageRepository
static readonly IMessageRepository repository = new MessageRepository();
實做CRUD
#region GET
public IEnumerable GetAll()
{
return repository.GetAll();
}
public MessageContext Get(int SerialNo)
{
MessageContext message = repository.Get(SerialNo);
if (message == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return message;
}
#endregion
#region POST
public HttpResponseMessage PostMessage(MessageContext msg)
{
MessageContext newMsg = repository.Add(msg);
var response = Request.CreateResponse(HttpStatusCode.Created, newMsg);
response.Headers.Location = new Uri(Request.RequestUri, "/api/messages/" + newMsg.SerialNo.ToString());
return response;
}
#endregion
#region DELETE
public MessageContext DeleteMessage(int SerialNo)
{
MessageContext message = repository.Remove(SerialNo);
if (message == null)
{
throw new HttpResponseException(HttpStatusCode.NoContent); //204
}
return message;
}
#endregion
#region
public void PutMessage(MessageContext msg)
{
if (!repository.Update(msg))
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); //404
}
}
#endregion
建立Route
在ASP.NET Web API,controller 是在處理 HTTP requests。而公開的方法通常稱為 action。當Web API framework 收到 HTTP Request 時,會被導到對應的 action。
在平常的 ASP.NET Web Page,並沒有啟用 routing table,所以要讓我們的 MessageController 能夠被呼叫。那就必須設定route table。
選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 New Item。
展開 Visual C#,在template 的清單上 選取 Web,然後在 右邊Panel 選取 Global Application Class,然後按 Add。
加入程式如下
using System.Web.Routing;
using System.Web.Http;
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{SerialNo}",
defaults: new { SerialNo = System.Web.Http.RouteParameter.Optional }
);
}
測試 Development Tool
在VS2012,Ctrl + F5。這時會出現
先不用理會,在IE開啟 F12 Development Tool,選擇Networking,然後按 Start capturing。在URL 請加上 /api/messages。
這時在你會看到 GET
選擇 Detailed View,然後Response body。你會看到 JSON format 的資料。
建立 ReadDemo Page
選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 New Item。展開 Visual C#,在template 的清單上 選取 Web,然後在 右邊Panel 選取 HTML Page,名稱GetDemo.htm,然後按 Add。
使用 JQuery,來呼叫剛做的Web API。你可以使用NuGet 或去 http://jquery.com/ 下載 JS 檔。
在Body 地方,HTML 如下
<body>
<form id="frmMessage">
<fieldset>
<legend>新增訊息</legend>
<label for="text">名稱</label>
<input id="txtName" name="txtName" type="text" value="" />
<label for="message">訊息</label>
<textarea id="txtMessage" name="text" style="width:400px"></textarea>
<button class="uibutton confirm" type="submit" >發佈</button>
</fieldset>
</form>
<p>
<button class="uibutton confirm" type="button" onclick="GetMessages();">Get Messages</button>
</p>
<div id="divBoardList">
</div>
</body>
在Header 的tag, 加入以下Script
function GetMessages(),結果如下
function GetMessageBySerialNo(),結果如下
建立 CRUD Page
選擇 MvcCRUDSample 專案,按右鍵 選擇New,然後 New Item。展開 Visual C#,在template 的清單上 選取 Web,然後在 右邊Panel 選取 HTML Page,名稱CRUDDemo.htm,然後按 Add。
在Body 地方,HTML 如下
<body>
<form id="frmMessage">
<fieldset>
<legend>新增訊息</legend>
<label for="text">名稱</label>
<input id="txtName" name="txtName" type="text" value="" />
<label for="message">訊息</label>
<textarea id="txtMessage" name="text" style="width:400px"></textarea>
<button class="uibutton confirm" type="submit" >發佈</button>
</fieldset>
</form>
<p>
<button class="uibutton confirm" type="button" onclick="GetMessages();">Get Messages</button>
</p>
<div id="divBoardList">
</div>
</body>
在Header 的tag, 加入以下Script
頁面如下
- 發佈 : POST
- Get Messages: GET
- 更新: PUT
- 刪除: DELETE
程式可在此下載MvcCRUDSample.zip






