如何在 ASP.NET Core 5 中過載 Action 方法

farsun發表於2021-09-09

ASP.NET Core 5 是一個開源的用於構建現代化web程式的開發框架,由於 ASP.NET Core 5 是基於 .NET Core 執行時,有了它,你可以將 web程式 執行在 Windows,Linux 和 Mac 上,值得注意的是, ASP.NET Core 5 整合了 Web API 和 MVC。

接下來回到本篇主題,何為方法過載? 就是讓多個不同簽名的方法共享一個方法名的技術,這種技術在 C# 中被廣泛使用,但用在 ASP.NET 5 中就不是那麼直觀了,這篇文章我們就來討論如何過載 Action。

action 是什麼

Action 就是 Controller 下標記為 public 並且 沒有被 [NonAction]特性標記的方法,如下程式碼:


    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }

雖然看起來和普通方法一樣,但是這些方法必須遵守下面這些約束。

  • Action 方法必須是 public

  • Action 不能是 static

  • Action 方法不能像 普通方法 一樣可以引數過載

當你建立好 MVC 專案,預設的 Index Action 也會自動建立,在 Startup.Configure 下的路由配置中也預設配置了此Action,如下程式碼所示:


    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

如果你不想使用預設的 Index,可以修改成其他你認為適合的,比如 Values


    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Values}/{id?}");
            });
        }
    }

使用相同的 謂語動詞 過載 action 方法

首先瞄一下 HomeController 類是啥樣子。


    public class HomeController : Controller
    {
        private readonly ILogger _logger;

        public HomeController(ILogger logger)
        {
            _logger = logger;
        }
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Index(string text)
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None,
        NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel
            {
                RequestId = Activity.Current?.Id ??
            HttpContext.TraceIdentifier
            });
        }
    }

注意上面類中我新增了一個 public IActionResult Index(string text) 方法,編譯器沒有給出任何錯誤提示,然而把應用程式跑起來,你會遇到一個執行時錯誤,如下圖所示:

圖片描述

使用不同的 謂語動詞 過載 action

現在修改一下 過載方法Index, 在新加入的過載方法上標上 HttpPost 特性,程式碼如下所示:


[HttpPost]
public IActionResult Index(string text)
{
   return View();
}

當再次執行應用程式,這次就沒有任何編譯時或者執行時錯誤了,如下圖所示:

圖片描述

使用 ActionName 特性 過載 action

可以透過 ActionName 特性實現 Action 方法的過載,值得注意的是,ActionName 特性中標記的名字不能相同,如下程式碼所示:


[ActionName("Index")]
public IActionResult Index()
{
    return View();
}
[ActionName("Index With Parameter")]
public IActionResult Index(string text)
{
     return View();
}

再次執行程式,一切都是ok的,沒有任何編譯時或者執行時錯誤,截圖如下:

圖片描述

使用 Route 特性 過載 action

你可以使用 RouteAttribute 特性來實現 action 過載,下面的程式碼片段展示瞭如何去實現。


public IActionResult Index()
{
    return View();
}
[Route("Home/Index/{i:int}")]
public IActionResult Index(int i)
{
    return View();
}
[Route("Home/Index/{isDeleted:bool}")]
public IActionResult Index(bool isDeleted)
{
    return View();
}

使用 NonAction 特性 過載 action

你可以使用 NonActionAttribute 來標記某些方法,從而在執行時讓 asp.net core 不把此方法 當作 action 對待,下面的程式碼展示了在 Index 上使用 NonActionAttribute 來實現 Index 的過載。


public IActionResult Index()
{
    return View();
}

[NonAction]
public IActionResult Index(string text)
{
    return View();
}

在 ASP.NET 5 中,如果兩個 action 的名字一樣,這就讓執行時很尷尬,因為它是以 action 為單位,所以一定會返回執行時錯誤,還有一點要注意的是,Action 的名字 是不區分大小寫的,也就是說:/Home/Index/HOME/INDEX 是一樣的,所以透過 url 的變化切入到各個 過載方法 中,這是一個很有技巧的技術,解決辦法就是透過本篇介紹的幾種方式來完美實現!

更多高質量乾貨:參見我的 GitHub: [csharptranslate] github.com/ctripxchuang/csharptranslate

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4289/viewspace-2826900/,如需轉載,請註明出處,否則將追究法律責任。

相關文章