iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
佛心分享-IT 人自學之術

學過一點 React,卻被撈進 C#:新手用 AI 硬啃 MVC 企業專案的 3 個月實錄系列 第 16

Day 16|一個 View 太長怎麼辦?Partial View 和 RenderSection 到底什麼時候用?

  • 分享至 

  • xImage
  •  

前兩篇整理完:

_Layout.cshtml
_ViewStart.cshtml
_ViewImports.cshtml

之後,我對 View 的結構終於比較有概念。

但實際繼續看專案時,又遇到兩個很容易搞混的東西:

Partial View
RenderSection

我一開始會覺得:

它們不都是把內容拆出去嗎?

那到底差在哪裡?

後來才慢慢整理出來:

Partial View
↓
把一塊局部畫面拆成另一支 .cshtml
需要時再重複使用

RenderSection
↓
Layout 先預留一個位置
讓個別 View 決定要不要把額外內容放進來

兩個看起來都跟「拆內容」有關,但實際用途其實不太一樣。

先看最簡單的差別

我會先這樣記:

Partial View
重點是「局部畫面」

RenderSection
重點是「Layout 的指定位置」

例如:

Header
Sidebar
共用表單區塊
共用查詢條件
使用者資訊
Modal

這些比較容易想到 Partial View。

而:

某頁專用 JavaScript
某頁專用 CSS
某頁額外區塊

這些比較容易想到 RenderSection。

先記這個方向,後面再慢慢拆。

Partial View 是什麼?

Partial View 可以先理解成:

把一小塊畫面拆成另一支 .cshtml,需要時再由其他 View 或 Layout 引用。

例如原本 _Layout.cshtml 可能寫很多東西:

<body>

    <header>
        <h1>網站名稱</h1>

        <nav>
            <a href="/">首頁</a>
            <a href="/Home/About">關於我們</a>
        </nav>
    </header>

    <main>
        @RenderBody()
    </main>

</body>

如果 Header 越寫越長,就可以把它獨立拆出去。

例如建立:

Views
└── Shared
    ├── _Layout.cshtml
    └── _Header.cshtml

_Header.cshtml

<header>

    <h1>網站名稱</h1>

    <nav>
        <a href="/">首頁</a>
        <a href="/Home/About">關於我們</a>
    </nav>

</header>

然後在 _Layout.cshtml 裡引用:

<body>

    <partial name="_Header" />

    <main>
        @RenderBody()
    </main>

</body>

這樣 Header 就被拆成一支獨立的 Partial View。

https://ithelp.ithome.com.tw/upload/images/20260813/20181499j8HUMD7tOw.png

為什麼要用 Partial View?

我目前會先把原因分成兩個。

第一個:避免同一塊畫面一直重複

假設很多頁面都有:

使用者基本資料

原本每一頁都可能寫:

<div class="user-info">
    <p>姓名:...</p>
    <p>Email:...</p>
    <p>部門:...</p>
</div>

如果這段同時出現在:

Detail.cshtml
Edit.cshtml
Profile.cshtml

之後版型要調整,就可能要改很多次。

這時可以把它拆成:

_UserInfo.cshtml

不同 View 再引用:

<partial name="_UserInfo" />

之後如果這塊畫面要修改,就可以集中處理。

第二個:避免一支 .cshtml 長到看不懂

企業專案裡一個頁面可能包含很多東西:

頁面標題
查詢條件
按鈕區
表格
明細 Modal
編輯 Modal
警告區塊

如果全部塞在:

Index.cshtml

裡面,很容易變成幾百行。

這時就可能拆成:

Index.cshtml
_SearchForm.cshtml
_UserTable.cshtml
_EditModal.cshtml

然後由 Index.cshtml 組合:

<h1>使用者管理</h1>

<partial name="_SearchForm" />

<partial name="_UserTable" />

<partial name="_EditModal" />

這樣打開 Index.cshtml 時,就比較容易先看懂:

這個頁面有哪些區塊

再依照需要進到個別 Partial View 看細節。

Partial View 一定要 _ 開頭嗎?

不是強制。

例如常看到:

_Header.cshtml
_UserTable.cshtml
_EditModal.cshtml

前面的 _ 是很常見的命名慣例。

可以先把它理解成是在提醒開發者:

這支通常不是完整頁面

而是某種共用或局部用途的 View

但 Partial View 的用途,不是單純看檔名有沒有 _ 就能決定。

因為前面已經看過:

_Layout.cshtml
_ViewStart.cshtml
_ViewImports.cshtml

它們也都有 _,但功能完全不同。

所以:

看到 _XXX.cshtml
↓
不能直接判斷它一定是 Partial View

還是要看它實際怎麼被使用。

Partial View 怎麼使用?

ASP.NET Core MVC 裡很常看到:

<partial name="_Header" />

也可能看到:

@await Html.PartialAsync("_Header")

如果 Partial View 需要自己的資料,也可以把 Model 傳進去。

例如:

<partial name="_UserInfo" model="Model.User" />

假設 _UserInfo.cshtml

@model UserViewModel

<div class="user-info">

    <p>@Model.Name</p>

    <p>@Model.Email</p>

</div>

外層 Detail.cshtml

@model UserDetailViewModel

<h1>使用者資料</h1>

<partial name="_UserInfo" model="Model.User" />

流程可以先理解成:

Detail.cshtml
↓
目前有 UserDetailViewModel

↓

把 Model.User
傳給 _UserInfo.cshtml

↓

_UserInfo.cshtml
使用自己的 UserViewModel

↓

產生使用者資訊區塊

所以 Partial View 不只是單純「把 HTML 拆出去」。

它自己也可以有:

@model

並接收外層傳進來的資料。

那 RenderSection 又是什麼?

RenderSection 常會寫在:

_Layout.cshtml

它和 Partial View 的方向不太一樣。

Partial View 是:

我有一塊畫面
想在這裡引用進來

RenderSection 比較像:

Layout 先在某個位置留一個洞

之後讓個別 View
決定要不要把自己的內容塞進這裡

最常見的例子就是:

頁面專用 JavaScript

例如 _Layout.cshtml 可能會有:

<body>

    <main>
        @RenderBody()
    </main>

    共用 JavaScript 放在這裡

    @await RenderSectionAsync("Scripts", required: false)

</body>

這裡:

@await RenderSectionAsync("Scripts", required: false)

可以先理解成:

Layout:

我在這裡預留一個叫 Scripts 的位置

↓

某個 View 如果有自己的 Scripts

↓

就放到這裡

View 要怎麼把內容塞進 Section?

例如 Index.cshtml

<h1>首頁</h1>

<p>這是首頁內容。</p>

@section Scripts {

    這裡放首頁專用的 JavaScript

}

這時可以拆成兩條:

Index.cshtml 的主要內容
↓
@RenderBody()

另外:

@section Scripts
↓
RenderSection("Scripts")

所以最後的頁面概念上會變成:

<body>

    <main>

        首頁
        這是首頁內容

    </main>

    共用 JavaScript

    首頁專用 JavaScript

</body>

所以可以記成:

@RenderBody()
↓
放目前 View 的主要內容

RenderSection("Scripts")
↓
放目前 View 額外提供的 Scripts 區塊

https://ithelp.ithome.com.tw/upload/images/20260813/20181499Q91zMiUQ3Z.png

required: false 是什麼?

例如:

@await RenderSectionAsync("Scripts", required: false)

裡面的:

required: false

代表:

Scripts 這個 Section
不是每一支 View 都一定要提供

所以某個 View 可以寫:

@section Scripts {

    這裡放這一頁專用的 JavaScript

}

另外一個 View 完全不寫:

@section Scripts

也沒關係。

如果改成:

@await RenderSectionAsync("Scripts", required: true)

則代表:

使用這個 Layout 的 View
必須提供 Scripts Section

如果沒有提供,就會造成執行時的錯誤。

因為不是每一個頁面都需要額外 JavaScript,所以實際上很常看到:

required: false

為什麼不直接把所有 JavaScript 都放 Layout?

假設只有:

使用者編輯頁

需要:

user-edit.js

如果直接把它當成共用 JavaScript 放進 _Layout.cshtml,那所有使用這個 Layout 的頁面都可能一起載入。

例如:

首頁
最新消息
使用者列表
報表

這些頁面根本不需要 user-edit.js

所以比較合理的方式可以是:

site.js
↓
全站共用
↓
由 Layout 統一載入

而:

user-edit.js
↓
只有 Edit.cshtml 需要
↓
由 Edit.cshtml 的 @section Scripts 提供

也就是:

共用 JavaScript
↓
Layout

頁面專用 JavaScript
↓
@section Scripts

這也是 RenderSection 很常見的使用情境。

RenderSection 只能放 JavaScript 嗎?

不是。

Scripts 只是很常見的例子。

Section 名稱其實可以自己定義。

例如 Layout 可以預留:

@await RenderSectionAsync("Styles", required: false)

某一支 View 再寫:

@section Styles {

    這裡放目前頁面的專用 CSS

}

這樣就可以做到:

共用 CSS
↓
Layout 統一處理

頁面專用 CSS
↓
@section Styles
↓
放進 Layout 預留的 Styles 位置

除了:

Scripts
Styles

也可能依照專案需求看到:

Toolbar
PageHeader
Actions

之類的 Section。

所以名稱不是 ASP.NET Core 規定只能叫:

Scripts

重點是:

Layout 定義的 Section 名稱

要和 View 提供的 @section 名稱一致

Partial View 和 RenderSection 到底差在哪裡?

這時候放在一起看就比較清楚。

項目 Partial View RenderSection
主要目的 拆出局部畫面供其他地方引用 讓 View 把內容放到 Layout 指定位置
內容在哪裡 通常是另一支 .cshtml 寫在目前 View 的 @section
誰決定位置 引用 Partial 的地方 Layout
誰提供內容 Partial View 目前 View
常見用途 Header、表單、列表、Modal、資訊區塊 頁面專用 JS、CSS、Toolbar 等
可以使用 Model 嗎 可以 Section 本身就是目前 View 的 Razor 內容
一定是共用內容嗎 不一定,但常用於拆分或重複使用 不一定,每個 View 可以提供不同內容

我自己會記成:

Partial View

「我有一塊局部畫面
想拆出去再引用」

而:

RenderSection

「Layout 有一個固定位置
讓目前 View 決定要放什麼」

用一個實際頁面一起看

假設我要做:

使用者編輯頁

可能會有:

_Layout.cshtml
↓
負責整個網站共用外框

_UserInfo.cshtml
↓
負責使用者資訊區塊

Edit.cshtml
↓
負責編輯頁主要內容

@section Scripts
↓
負責這一頁自己的 JavaScript

_Layout.cshtml

<body>

    <header>
        共用 Header
    </header>

    <main>
        @RenderBody()
    </main>

    共用 JavaScript

    @await RenderSectionAsync("Scripts", required: false)

</body>

Edit.cshtml

@model EditUserViewModel

<h1>編輯使用者</h1>

<partial name="_UserInfo" model="Model.User" />

<form>
    ...
</form>

@section Scripts {

    這裡放編輯頁專用 JavaScript

}

_UserInfo.cshtml

@model UserViewModel

<div class="user-info">

    <p>姓名:@Model.Name</p>

    <p>Email:@Model.Email</p>

</div>

整體關係就是:

_Layout.cshtml
↓
控制整個頁面的大框架

@RenderBody()
↓
放 Edit.cshtml 的主要內容

↓

Edit.cshtml 裡引用 _UserInfo.cshtml

↓

Partial View 顯示使用者資訊

另外:

Edit.cshtml 的 @section Scripts
↓
放進 Layout 的 Scripts Section

這樣就比較容易看出:

Partial View
和
RenderSection
其實是在處理不同方向的事情

那 Partial View 可以放在 Layout 裡嗎?

可以。

例如:

<partial name="_Header" />

就很常直接寫在 _Layout.cshtml 裡。

所以不要把 Partial View 理解成:

只能給一般 View 使用

它其實比較像:

哪裡需要這塊局部畫面
哪裡就可以引用

例如:

_Layout.cshtml
↓
引用 _Header.cshtml

Index.cshtml
↓
引用 _SearchForm.cshtml

Edit.cshtml
↓
引用 _UserInfo.cshtml

重點是:

把局部畫面拆成獨立 View
再由需要的地方引用

我怎麼判斷該用 Partial View 還是 RenderSection?

現在如果碰到需求,我會先問兩個問題。

第一個:

這是一塊可以獨立出來的畫面嗎?

例如:

Header
查詢條件
卡片
使用者資訊
Modal
表格

如果是,我會先想到:

Partial View

第二個:

這是目前 View
想把某段內容放到 Layout 的特定位置嗎?

例如:

這頁專用 JavaScript
這頁專用 CSS
這頁自己的 Toolbar

這時我就會先想到:

RenderSection

所以可以縮成:

想拆出一塊局部畫面?
↓
Partial View

想讓目前 View
把內容送到 Layout 指定的位置?
↓
RenderSection

實際追企業專案時,我會怎麼找?

假設我在 View 裡看到:

<partial name="_SearchForm" />

但不知道內容在哪裡。

我會:

看到 _SearchForm
↓
搜尋 _SearchForm
↓
找到 _SearchForm.cshtml
↓
打開確認內容
↓
再看它有沒有 @model

如果看到:

@section Scripts {

    ...
}

但不知道這段內容最後會跑到哪裡。

我會反過來搜尋:

RenderSection

找到 Layout 裡:

@await RenderSectionAsync("Scripts", required: false)

再看它實際位在哪裡。

所以追法可以直接記成:

看到 <partial>
↓
找另一支 .cshtml

看到 @section
↓
往 Layout 找 RenderSection

這兩條在看陌生專案時很好用。

修改時要注意什麼?

Partial View 很可能被很多地方引用。

所以如果修改:

_UserInfo.cshtml

不要只測目前這一頁。

我會先搜尋:

_UserInfo

看看哪些地方有引用。

可能同時出現在:

Detail.cshtml
Edit.cshtml
Profile.cshtml

這時修改 _UserInfo.cshtml,三個頁面都有可能被影響。

而如果修改 Layout 裡的:

@await RenderSectionAsync("Scripts", required: false)

影響範圍可能更大。

因為所有使用這個 Layout 的 View,都可能跟這個 Section 有關。

所以這幾天其實一直有同一個觀念:

越共用的東西
↓
修改前越要先確認影響範圍

不要只看到目前畫面正常,就以為其他頁一定沒問題。

這篇先記住什麼?

Partial View 可以先記成:

把一塊局部畫面
拆成另一支 .cshtml

例如:

<partial name="_Header" />

常見用途像:

Header
Sidebar
表單
列表
Modal
共用資訊區塊

而 RenderSection 可以先記成:

Layout 先預留一個指定位置

↓

由目前 View
決定要不要提供額外內容

例如 Layout:

@await RenderSectionAsync("Scripts", required: false)

View:

@section Scripts {

    這裡放目前頁面的專用 JavaScript

}

最簡單的判斷方式就是:

Partial View
=
我要拆出「這一塊局部畫面」

RenderSection
=
我要把「這一頁自己的額外內容」
放到 Layout 指定的位置

到這裡,前面幾天整理的 View 結構就可以完整串起來:

_ViewStart.cshtml
↓
提供 View 執行時的共用設定
最常用來指定 Layout

_ViewImports.cshtml
↓
提供 Razor 共用匯入

_Layout.cshtml
↓
提供頁面共用外框

@RenderBody()
↓
放目前 View 的主要內容

Partial View
↓
拆出局部畫面
需要時再引用

RenderSection
↓
讓目前 View
把額外內容放進 Layout 指定位置

到這裡,View 這一塊終於比較不像一開始看到的:

一堆 .cshtml 到底誰在包誰?

接下來就可以開始離開 View,往 Controller 走。

下一篇要看:

我在網址輸入 /Home/Index 之後,MVC 到底怎麼知道要找到 HomeController,再執行 Index()


上一篇
Day 15|`_ViewStart.cshtml` 和 `_ViewImports.cshtml` 都有底線,到底各自負責什麼?
下一篇
Day 17|輸入網址之後發生什麼事?從 Route 找到 Controller 和 Action
系列文
學過一點 React,卻被撈進 C#:新手用 AI 硬啃 MVC 企業專案的 3 個月實錄17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言