筆記目錄

Skip to content

ASP.NET Core Web API 入門心得 - 淺談 non-RESTful 的 Route 覆寫

在使用 non-RESTful 風格的 Web API 中,通常會使用 Controller/Action 的格式來定義大部分的 URL。為了避免在每個 Controller 或 Action 中都重複設定路由,可以建立一個 BasicController 來統一設定路由,如下所示:

csharp
[ApiController]
[Route("[controller]/[action]")]
public abstract class BasicController : ControllerBase {
}

public class TestRouteController : BasicController {
    // URL:/TestRoute/TestAction
    [HttpPost]
    public void TestAction() {

    }
}

透過這種方式,就不需要在每個 Controller 或 Action 中再次指定路由。但如果遇到像我這種白目、第一次參與前後端分離的專案、對公司專案架構不熟,最後開發出來的 API URL 與現有架構差異過大,導致被前端拿刀來砍的情況下,雖然可以使用 [jsonPropertyName] 來處理輸入和輸出的屬性名稱,但對於路由定義在 BasicController 上的情況,如果不想要走回每個 Action 個別設定,就只能透過覆寫不同路由來解決這個問題(當然像我這種幾乎都不一樣就另一回事)。

在 ASP.NET Core 中,[Route] 屬性在 Controller 和 Action 上的處理效果有所不同。若加在 Controller 上,將覆寫 BasicController 的路由設定;若加在 Action 上,則會與 Controller 的設定進行串接。以下提供了幾種使用情境的範例:

csharp
[ApiController]
[Route("[controller]/[action]")]
public abstract class BasicController : ControllerBase {
}

[Route("Override/[action]")]
public class TestRouteController : BasicController {
    // 情境:Controller 覆寫 Route,Action 不處理
    // URL:/Override/OverrideController
    [HttpPost]
    public void OverrideController() {
    }

    // 常見誤用情境:Controller 和 Action 都覆寫 Route,導致 Action 的 URL 是兩者 Route 的串接
    // URL:/Override/OverrideAction/Action/OverrideAction
    [HttpPost]
    [Route("Action/[action]")]
    public void OverrideAction() {
    }

    // 情境:Action 不想使用 Controller 設定的 Route,在 Route 最前面加上 "/"
    // URL:/Action/OnlyAction
    [HttpPost]
    [Route("/Action/[action]")]
    public void OnlyAction() {
    }

    // 情境:Action 不想使用 Controller 設定的 Route,在 Route 最前面加上 "~",效果同上
    // URL:/Action/OnlyAction2
    [HttpPost]
    [Route("~/Action/[action]")]
    public void OnlyAction2() {
    }

    // 情境:單純只想要修改 Action 名稱
    // URL:/Override/Rename
    [HttpPost]
    [ActionName("Rename")]
    public void RenameAction() {
    }
}

異動歷程

  • 2024-04-16 初版文件建立。