[ASP.Net Core] 使用 ViewComponent 檢視元件取代 Html.Action() 的呼叫

using ViewComponent  replace Html.Action() in Asp.Net Core

前言

以往在ASP.net MVC時期,在View(*.cshtml)習慣使用 @Html.Action() 呼叫child action來實作具有商業邏輯的部份檢視(PartialView)

但在ASP.net Core年代,微軟建議改成ViewComponent寫法,效能會比較好

以下我整理了簡易程式碼,方便工作中馬上套用

官方文件:View components in ASP.NET Core

實作

1.在網站根目錄下新增一個名為「ViewComponents」資料夾,此目錄下要放置商業邏輯的.cs檔,也就是ViewComponent,名稱隨意取

專案資料夾

商業邏輯 ViewComponent 的.cs檔如下↓


using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

namespace Demo.ViewComponents
{
    //須繼承ViewComponent
    public class ShowUserInfo : ViewComponent
    {
        //用這個: async Task<IViewComponentResult> InvokeAsync
        //要接的參數隨意
        public async Task<IViewComponentResult> InvokeAsync(int age, string name)
        {
            ViewData["age"] = age;
            ViewBag.name = name;
            return View();
        } 
    }
}

2.在 Views/Shared/Components/{View Component Name}/ 路徑下建立一個Default.cshtml檔

※2021-05-01追記:Asp.net Core搜尋View檢視的順序

本文的ViewComponentName取名:ShowUserInfo,所以完整路徑會是如下圖

Default.cshtml的代碼如下

@{
    //即使Views/Shared目錄下有_Layout.cshtml及_ViewStart.cshtml兩個檔案
    //ViewComponents預設不套用Master Page,有需要得自己指定↓不過應該沒人在ViewComponents套Layout就是
    //Layout = "_Layout";
}


<!--重點在這↓-->
<div>
    <span>您的年紀:</span>@ViewData["age"]
    <span>您的姓名:</span>@ViewBag.name
</div>




<!--↓呈現在_Layout.cshtml的 RenderSection("inlineScript") 位置,視需要看自己要不要加↓-->
@section inlineScript
{
    <script>
             //略...
    </script>
}

3.接著在其他的View檢視(*.cshtml) 叫用ViewComponent的寫法↓

<!--引用你的ViewComponent命名空間-->
@using Demo.ViewComponents

<!--檢視元件-->
@await Component.InvokeAsync(nameof(ShowUserInfo), new   { age = 30, name="高級打字員" })

本文範例寫在Index.cshtml,完整代碼如下↓

※2021-04-11追記,ViewComponent的tag Helper叫用方法

1.先在Views/_ViewImports.cshtml寫下↓


@addTagHelper *, ViewComponent所在專案的組件名稱

組件名稱在Visual Studio中,對著專案右鍵→屬性便看得到

2.在 View(*.cshtml) 中以tag Helper方式叫用ViewComponent↓

<!--檢視元件-->  
<vc:show-user-info age="30" name="高級打字員"/>

↑ViewComponent 的類別名稱原本命名ShowUserInfo,只要在 View(*.cshtml)裡 輸入 <vc:s 當輸入s開頭的那一剎那

Visual Studio就會出現intellisense提示你接下來該輸入show-user-info

↑若ViewComponent(*.cs檔)的InvokeAsync()方法有定義輸入參數的話,tag Helper在叫用時參數全部必填,否則不work

以Component.InvokeAsync來叫用,則參數不用全部必填

↑如果ViewComponent(*.cs檔)類別名稱重新命名的話,tag Helper的標籤名稱不會透過Visual Studio連動重構修改,記得要自己手動修改tag Helper的標籤名稱

4.這樣就完成了,執行Index.cshtml的結果↓

結語

ViewComponent相比 ASP.net MVC時期的 @Html.Action,有以下幾點需留意:

  • 不參與控制器生命週期,無法使用Filter
  • 非 HTTP 端點的呼叫,不處理Http Request/Response ,ViewComponent是透過程式碼叫用 。 

如果你不想用預設的Default.cshtml當做ViewComponent的檢視名稱,請參考官網:檢視 ASP.NET Core 中的元件 - 指定檢視名稱 | Microsoft Docs