[ASP.NET] Web API 路由
在上一篇筆者簡單介紹了Web API in web form的開發,如果您是寫慣了web form的開發者,可能會發現到在開發Web API 時多了一個在web form開發上比較少見的東西,那就是路由(Route),反之若您是ASP.NET MVC的開發者,對於路由這個東西應該就會比較清楚了。
我們先來看一下Web API 是怎麼訂路由的,在Global.asax裡我們是這麼寫的
void Application_Start(object sender, EventArgs e)
{
// 應用程式啟動時執行的程式碼
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterOpenAuth();
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "webapi/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
}
在routeTemplate所定的路由樣版格式為 : "webapi/{controller}/{id}" ,其中webapi為路徑片段,表示我們在呼叫Web API 時,會是Http : // … / webapi ,而{controller}及{id}則為位置變數,當接收到來自於Http的Request時則會嘗試比對路由表,除了第一段的路徑片段字串及第二段的位置變數之外,其餘的位置變數則會被視為Web API 方法的參數
(1)如果接收到 Http : // … / webapi / employee 時,嘗試比對路由表,{controller}的位置則會是employee ,所以就會看看是否有employee 這個ApiController
(2)若是接收到 Http : // … / webapi / employee / 1 ,同樣的嘗試比對路由表,{controller}的位置則會是employee ,並且會找看看是否有符合傳入1個參數名稱為id的方法
談到這裡或許您會有個疑問,我們在呼叫Web API 時並沒有告知是要呼叫Web API 裡的哪一個方法,為什麼Web API 會知道要去找哪一個方法來回應請求呢 ? 這是因為在Web API 的設計裡有個暗規則,這個規則就是會以您的請求方式(Get / Post / Put / Delete )找詢跟請求方式相同的開頭命名的方法,舉例來說 : 如果您的請求是Get ,那麼就會去找該Controller裡以Get開頭命名的方法來回應,同樣的如果您的請求是Post ,那麼就會去找該Controller裡以Post開頭命名的方法來回應,以此類推。
所以從上面所談及的,您會發現如何定義您的Web API 路由跟您的Web API 方法的設計會有很大的關係,舉例來說,如果我們的Web API 裡有二個以Get為開頭命名的方法,並且都具入傳入一個名為id的參數,分別如下
public String GetByID(int id)
{
return "GetByID";
}
public String Get(int id)
{
return "Get";
}
而我們的路由定義如下
void Application_Start(object sender, EventArgs e)
{
// 應用程式啟動時執行的程式碼
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterOpenAuth();
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "webapi/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
}
接著我們以POSTMAN工具來測試一下,結果會出現Multiple actions were found that match the request的錯誤訊息,而這訊息主要是說在我們的WebAPI裡找到多個符合路由所定義的方法。因為我們的GetByID 及 Get 這二個方法都具有傳入名稱為id的參數,由路由所定義的{controller}/{id}一比對起來二個方法都符合,就會不知道要哪一個方式來做為回應請求,因此就會引發錯誤。
接著我們再設計一個情境,假設路由定義如下
void Application_Start(object sender, EventArgs e)
{
// 應用程式啟動時執行的程式碼
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterOpenAuth();
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "webapi/{controller}/{name}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
}
接著我們的WebAPI方法撰寫如下
public String GetByID(int id)
{
return "GetByID";
}
同樣的,以POSTMAN工具來測試一下,結果會出現以下的錯誤訊息,這訊息告訴我們無法找跟路由定義匹配的方法,而原因在於WebAPI方法我們設計為傳入名為id的參數,但在路由裡我們卻定義了{name}的參數範本,所以結果就會產生不匹配。
以上簡單說明關於WebAPI路由的定義,以及跟設計WebAPI方法間的關係,希望對大家有所幫助。
By No.18