摘要:[WebAPI]如何建立WebAPI Client(Console + Web)(C#)
此Client乃是針對前例建立的WebAPI 2
[WebAPI]實作查詢+新增編輯刪除功能WebAPI2(新增Routing機制以及動態LINQ)
Web的大概沒人還特地postback回後端才去存取WebAPI吧,應該都用jQuery去做了,而且jQuery做還有Ajax效果
但是c#版本的畢竟還是需要,像是WinForm, WPF, Window Service...這裡就用WinForm的非同步效果做示範
先實作Winform的方式呼叫WebAPI
先建立一個Winform專案
NuGet安裝WebAPI專用的http Client Library(WebAPI OOXX Http Client OOXX),
它會自動安裝http client library 以及 json.net套件:
然後新增一個非同步的function如下, 這是利用之前建立的WebAPI去查詢所有人員的姓名:
用非同步的方式的原因是因為,http client的get, post, put, delete都是非同步的
所以整個function也必須是非同步的,好處就是winform按下其中一個按鈕之後,不會導致
整個畫面鎖住,還是可以繼續按其他的按鈕。
我們首先把處理資料的動作獨立出來一個類別EmployeeDbContext.cs
然後加入下列程式碼來取得所有員工姓名
string baseAddr = "http://localhost:444/";
///
/// 取得所有員工資料
///
///
public async Task GetAllEmpNames()
{
string empNames = "";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddr);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/Employee");
//response.EnsureSuccessStatusCode(); // Throw if not a success code.
if (response.IsSuccessStatusCode)
{
var employees = await response.Content.ReadAsAsync>();
foreach (var e in employees)
{
empNames += e.FirstName + " " + e.LastName + "\n";
}
}
return empNames;
}
} /string>
然後在畫面上拉幾個簡易的控制項如下:
然後設定(查詢)的按鈕的動作,Sum()是故意拖延時間,體驗一下非同步的好處
拖延的那幾秒鐘,仍然可以按下別的按鈕:
private async void btnQuery_Click(object sender, EventArgs e)
{
EmployeeDbContext db = new EmployeeDbContext();
lblQueryStatus.Text = "查詢中...";
await Task.Run(() => { return Sum(); });//故意delay
lblQueryResult.Text = await db.GetAllEmpNames();
lblQueryStatus.Text = "查詢完畢!";
}
private async Task Sum()
{
Stopwatch st = new Stopwatch();
int sum1 = 0;
st.Start();
for (int i = 0; i < int.MaxValue; i++)
{
sum1 += i + 1;
}
st.Stop();
//return "\n故意Delay\n" + (st.ElapsedMilliseconds / 1000).ToString() + "秒";
}
下面是查詢的結果:
然後介紹(新增)Post
為了將來要實作Model.IsValid,也為新增的動作加入一個類別EmployeeInsert
class EmployeeInsert
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public Nullable BirthDate { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string EmpType { get; set; }
}
然後利用以下程式碼存取WebAPI, 以進行資料新增
public async Task InsertNewEmp(EmployeeInsert newEmp)
{
Boolean insertSuccess = false;//是否新增資料成功
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddr);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.PostAsJsonAsync("api/Employee/Insert", newEmp);
if (response.IsSuccessStatusCode)
{
//根據http 1.1, 回傳的header.location會有剛剛送出的網址
//即http://localhost:444/api/Employee/Insert
//既然回傳了就順便取出來
Uri newEmpUri = response.Headers.Location;
insertSuccess = true;
}
}
return insertSuccess;
}
最後定義按下insert按鈕的事件:
private async void btnInsert_Click(object sender, EventArgs e)
{
//新增都是以建立Employee物件的方式進行,因為這樣才能順便一起把Model.isValid做好
EmployeeDbContext db = new EmployeeDbContext();
Boolean insertSuccess = false;//是否新增成功
EmployeeInsert emp = new EmployeeInsert();
string nowString = DateTime.Now.ToString("MMddhhmmss");
emp.FirstName = "Yen" + nowString;
emp.LastName = "ChiaChi" + nowString;
emp.City = "New Taipei City" + nowString;
try
{
insertSuccess = await db.InsertNewEmp(emp);
if(insertSuccess == true)
{
lblInsertResult.Text = "新增成功!";
}
else
{
lblInsertResult.Text = "新增失敗!";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
按下新增按鈕後,畫面顯示新增成功:
接下來示範更新update:
新增一個EmployeeUpdate類別,以供未來做Model驗證之用
class EmployeeUpdate
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string City { get; set; }
}
然後在EmployeeDbContext.cs加入程式碼,利用Put method去更新資料
public async Task UpdateEmp(int EmployeeID ,EmployeeUpdate updateEmp)
{
Boolean updateSuccess = false;//是否更新資料成功
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddr);
//client.BaseAddress = new Uri("http://localhost:2394/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP Put
HttpResponseMessage response = await client.PutAsJsonAsync("api/Employee/Update/" + EmployeeID, updateEmp);
if (response.IsSuccessStatusCode)
{
updateSuccess = true;
}
}
return updateSuccess;
}
按下編輯按鈕的時候,會去執行update員工資料,一樣是用非同步的方式去寫
private async void btnEdit_Click(object sender, EventArgs e)
{
//新增都是以建立Employee物件的方式進行,因為這樣才能順便一起把Model.isValid做好
lblEditStatus.Text = "修改中...";
EmployeeDbContext db = new EmployeeDbContext();
Boolean updateSuccess = false;//是否update成功
EmployeeUpdate updateEmp = new EmployeeUpdate();
string nowString = DateTime.Now.ToString("MMddhhmmss");
updateEmp.FirstName = "FirstNameChangedTo" + nowString;
updateEmp.LastName = "LastNameChangedTo" + nowString;
updateEmp.City = "CityChangedTo" + nowString;
//await Task.Run(() => { return Sum(); });//故意delay
try
{
updateSuccess = await db.UpdateEmp(15, updateEmp);
if (updateSuccess == true)
{
lblEditResult.Text = "修改成功!";
}
else
{
lblEditResult.Text = "修改失敗!";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
最後按下修改按鈕,顯示修改成功
然後示範刪除:
首先於EmployeeDbContext.cs加入程式碼,利用WebAPI去刪除資料
public async Task DeleteEmp(int EmployeeID)
{
Boolean delSuccess = false;//是否刪除資料成功
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddr);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP delete
HttpResponseMessage response = await client.DeleteAsync("api/Employee/Delete/" + EmployeeID);
if (response.IsSuccessStatusCode)
{
delSuccess = true;
}
}
return delSuccess;
}
然後在刪除的按鈕加入上述刪除的動作
private async void btnDel_Click(object sender, EventArgs e)
{
lblDelStatus.Text = "刪除中...";
EmployeeDbContext db = new EmployeeDbContext();
Boolean delSuccess = false;//是否刪除成功
delSuccess =await db.DeleteEmp(40);
if (delSuccess == true)
{
lblDelResult.Text = "刪除成功!";
}
else
{
lblDelResult.Text = "刪除失敗!";
}
}
然後執行之後,按下刪除按鈕,顯示刪除成功
這樣子C#版本的Client去使用WebAPI就算完成囉
下一篇要寫jQuery版本的
PS.突然想起來一個重點,要怎麼用C#去做Authentication去呼叫https的WebAPI?
研究一下,如果研究出來再來這邊補充
參考資料:
Calling a Web API From a .NET Client (C#)