[ASP.NET] Web API 路由

  • 6343
  • 0

[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}一比對起來二個方法都符合,就會不知道要哪一個方式來做為回應請求,因此就會引發錯誤。

image

 

接著我們再設計一個情境,假設路由定義如下

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}的參數範本,所以結果就會產生不匹配。

image

 

以上簡單說明關於WebAPI路由的定義,以及跟設計WebAPI方法間的關係,希望對大家有所幫助。

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18