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 方法的時候務必要小心使用。

相關連結