The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

ASP.NET MVC 開發心得分享 (7):HandleUnknownAction

使用 ASP.NET MVC 開發網站的過程中,在 Controller 中的 Action 名稱有可能因為某些理由而想要更名(Rename),但在 View 中的連結若忘記改或因為連結在資料庫裡沒改到的話,就會導致 Request 到一個不存在 Action 進而得到 HTTP 404 找不到資源 的結果 (如下圖示),今天我就來分享處理這種情況的方式。

'/' 應用程式中發生伺服器錯誤。找不到資源。 描述: HTTP 404. 您要尋找的資源 (或其相依性的其中之一) 可能已經移除、名稱已經變更或是暫時無法使用。請檢閱下列 URL,並且確定它的拼寫無誤。

我們都知道 ASP.NET MVC 中所有的 Controller 都���繼承 Controller 這個抽象類別 (如下圖示)

 ASP.NET MVC 中所有的 Controller 都是繼承 Controller 這個抽象類別

而在 Controller 抽象類別中有定義一個 HandleUnknownAction 方法,預設的行為就是回應 HTTP 404,如下圖所示 0x194 就等於十進位的 404

在 Controller 抽象類別中有定義一個 HandleUnknownAction 方法,預設的行為就是回應 HTTP 404,如圖示 0x194 就等於十進位的 404

若你要自訂回應方式,就可以在每一個 Controller 中覆寫這個方法,或是在自己定義的 BaseController 中覆寫這個方法,如下程式範例:

protected override void HandleUnknownAction(string actionName)
{
    Response.Redirect("/", true);
}

程式碼圖示如下:

在 Controller 抽象類別中有定義一個 HandleUnknownAction 方法,預設的行為就是回應 HTTP 404,若你要自訂回應方式,就可以在每一個 Controller 中覆寫這個方法,或是在自己定義的 BaseController 中覆寫這個方法

如上範例是我習慣的寫法,直接將無效的 Request 直接 Redirect 回首頁,但建議不要在「開發時期」就這樣寫,這樣子你就很難抓錯誤了。如果網站已經部署至正式機,建議可以將這些 UnknownAction 都記錄下來備查。

如果你直接參照 MSDN 上的範例程式的話,會有一個潛在的風險,初學者要特別注意。

MSDN 上的範例程式如下:

protected override void HandleUnknownAction(string actionName) {
    try {
        this.View(actionName).ExecuteResult(this.ControllerContext);
    } catch (InvalidOperationException ieox ) {
        ViewData["error"] = "Unknown Action: \"" + 
            Server.HtmlEncode(actionName) + "\"";
        ViewData["exMessage"] = ieox.Message;
        this.View("Error").ExecuteResult(this.ControllerContext);
    }
}

如果你的 Controller 中有個如下圖的 Action 並套用了 [AcceptVerbs(HttpVerbs.Post)] 屬性(Attribute)

image

而且也沒有另一個 Login Action 存在的情況下,當使用者直接點擊 Login 這個網址 ( 以 HTTP GET ),就會觸發 HandleUnknownAction 方法,原本你可能預期這個 Login View 在 HTTP GET 情況下不應該被顯示,但因為利用以下這行 Code 的方式直接執行名為 actionName 的 View,原本因為在 HTTP POST 才顯示的 View 就會被顯示出來!

this.View(actionName).ExecuteResult(this.ControllerContext);

所以在使用 HandleUnknownAction 方法的時候務必要小心使用。

相關連結