iT邦幫忙

2026 iThome 鐵人賽

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

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

Day 15|`_ViewStart.cshtml` 和 `_ViewImports.cshtml` 都有底線,到底各自負責什麼?

  • 分享至 

  • xImage
  •  

上一篇整理完 _Layout.cshtml 之後,我終於知道:

Layout
負責共用外框

View
負責目前頁面內容

@RenderBody()
負責把 View 放進 Layout

但實際看專案時,又會看到另外兩支很容易搞混的檔案:

_ViewStart.cshtml
_ViewImports.cshtml

兩個都有底線。

而且通常都會在 Views 的資料夾階層裡看到。

兩個也都不是一般拿來直接顯示畫面的 View。

所以我一開始真的很容易把它們混在一起。

後來才慢慢整理出來:

_ViewStart.cshtml
比較像是在處理:
「View 開始執行時,要先套哪些共用設定?」

_ViewImports.cshtml
比較像是在處理:
「這些 View 可以共用哪些 Razor 匯入設定?」

這篇就直接用實際專案裡最常見的用法來分。

先看最簡單的差別

可以先記:

_ViewStart.cshtml
主要處理 View 執行時的共用設定

_ViewImports.cshtml
主要處理 Razor View 共用的匯入設定

最常看到的內容也完全不一樣。

_ViewStart.cshtml 可能是:

@{
    Layout = "_Layout";
}

_ViewImports.cshtml 可能是:

@using MyProject
@using MyProject.ViewModels
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

所以如果只想先快速判斷:

看到 Layout
→ 先想到 _ViewStart.cshtml

看到 @using、@addTagHelper
→ 先想到 _ViewImports.cshtml

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

_ViewStart.cshtml 到底在做什麼?

上一篇有提到,一般 View 可以自己指定 Layout:

@{
    Layout = "_Layout";
}

例如:

@{
    Layout = "_Layout";
}

<h1>首頁</h1>

這樣當然可以。

但如果專案有很多 View:

Index.cshtml
Create.cshtml
Edit.cshtml
Detail.cshtml
History.cshtml

每一頁都重複寫:

@{
    Layout = "_Layout";
}

就很麻煩。

所以通常會把這種共用設定放進:

_ViewStart.cshtml

例如:

@{
    Layout = "_Layout";
}

這樣底下很多 View 就不需要每一頁都自己重複指定 Layout。

實際結構可能長這樣

Views
├── _ViewStart.cshtml
│
├── Home
│   ├── Index.cshtml
│   └── About.cshtml
│
└── Shared
    └── _Layout.cshtml

_ViewStart.cshtml

@{
    Layout = "_Layout";
}

Index.cshtml

<h1>首頁</h1>

About.cshtml

<h1>關於我們</h1>

雖然這兩支 View 都沒有自己寫:

Layout = "_Layout";

但執行時還是可以套用 _ViewStart.cshtml 裡設定的 Layout。

可以先理解成:

準備執行目前 View
↓
先套用 _ViewStart.cshtml 的設定
↓
取得 Layout
↓
執行目前 View
↓
再和 Layout 組成最後畫面

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

所以 _ViewStart.cshtml 只是拿來設定 Layout 嗎?

不只。

它的概念其實比較接近:

在 View 開始執行時
先跑一段共用 Razor 設定

例如也可能看到:

@{
    Layout = "_Layout";

    ViewData["SystemName"] = "管理系統";
}

不過實際專案最常見、也最值得先記住的還是:

Layout = "_Layout";

所以初學時,可以先直接把:

_ViewStart.cshtml
↓
預設 Layout

連在一起。

之後遇到更複雜的用法,再慢慢往外擴充就好。

某一頁可以不用 _ViewStart.cshtml 指定的 Layout 嗎?

可以。

假設 _ViewStart.cshtml 是:

@{
    Layout = "_Layout";
}

代表一般頁面預設使用:

_Layout.cshtml

但登入頁可能不需要 Header、Sidebar,而是想使用另一套版型。

這時 Login.cshtml 可以自己指定:

@{
    Layout = "_LoginLayout";
}

例如:

Views
├── _ViewStart.cshtml
│
├── Shared
│   ├── _Layout.cshtml
│   └── _LoginLayout.cshtml
│
└── Account
    └── Login.cshtml

_ViewStart.cshtml

@{
    Layout = "_Layout";
}

Login.cshtml

@{
    Layout = "_LoginLayout";
}

<h1>登入</h1>

這時登入頁就會使用:

_LoginLayout.cshtml

所以可以理解成:

_ViewStart.cshtml
提供共用的預設設定

↓

某一支 View
如果有自己的需求

↓

可以再自行指定

_ViewImports.cshtml 又是什麼?

這支檔案做的事情就完全不一樣了。

假設 View 裡要使用:

@model UserViewModel

UserViewModel 實際上位在:

MyProject.ViewModels

如果 Razor View 沒有匯入這個命名空間,可能就要寫成完整名稱:

@model MyProject.ViewModels.UserViewModel

如果很多 View 都會用到這個 namespace,每一頁都這樣寫會很長。

所以可以在:

_ViewImports.cshtml

統一加入:

@using MyProject.ViewModels

之後 View 就可以直接寫:

@model UserViewModel

不用每一頁都重複寫完整 namespace。

_ViewImports.cshtml 常放什麼?

例如:

@using MyProject
@using MyProject.ViewModels

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

初學時可以先分成兩個最常見的東西:

@using

@addTagHelper

@using 是什麼?

例如:

@using MyProject.ViewModels

跟一般 C# 裡:

using MyProject.ViewModels;

概念很接近。

目的就是讓 Razor View 可以直接使用這個 namespace 裡面的類別。

例如原本可能要寫:

@model MyProject.ViewModels.UserViewModel

加入:

@using MyProject.ViewModels

之後就可以簡化成:

@model UserViewModel

所以看到:

@model UserViewModel

但目前這支 View 上面完全沒有:

@using MyProject.ViewModels

先不要急著覺得奇怪。

可以去找:

_ViewImports.cshtml

有可能早就在那裡共用匯入了。

@addTagHelper 又是什麼?

ASP.NET Core MVC 的 View 裡常會看到:

<form asp-controller="User"
      asp-action="Create"
      method="post">
</form>

或者:

<input asp-for="Name" />

裡面的:

asp-controller
asp-action
asp-for

不是一般 HTML 原本就有的屬性。

它們是 ASP.NET Core MVC 的 Tag Helper。

_ViewImports.cshtml 裡常會看到:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

可以先理解成:

把 ASP.NET Core MVC 內建的 Tag Helper
提供給這些 Razor View 使用

這樣 View 裡才可以使用像:

asp-for
asp-action
asp-controller

這些 MVC 提供的功能。

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

所以 _ViewImports.cshtml 是「幫 View 少寫東西」嗎?

某種程度上可以先這樣理解。

如果沒有共用匯入,每一支 View 可能都要自己寫:

@using MyProject.ViewModels
@using MyProject.Helpers

有了 _ViewImports.cshtml 之後:

共用的 Razor 匯入設定
↓
集中寫一次
↓
底下很多 View 都可以使用

所以我會把它先記成:

Razor View 的共用匯入區

_ViewStart.cshtml_ViewImports.cshtml 最大差別

直接放在一起最好記。

檔案 主要負責 常見內容
_ViewStart.cshtml View 執行時的共用設定 Layout = "_Layout"
_ViewImports.cshtml Razor View 共用匯入 @using@addTagHelper

我自己會先記成:

_ViewStart
決定 View「開始時要套什麼設定」

_ViewImports
決定 View「可以直接使用什麼」

再具體一點:

_ViewStart.cshtml
↓
這頁預設要套哪個 Layout?

_ViewImports.cshtml
↓
這頁有哪些 namespace、Tag Helper 可以直接使用?

這樣就比較不容易搞混。

兩個檔案都會直接顯示畫面嗎?

不會。

它們都不是像:

Index.cshtml
Create.cshtml
Edit.cshtml

這種主要負責顯示頁面內容的 View。

所以通常不會把真正的頁面內容寫在裡面,例如:

<h1>首頁</h1>

<button>新增</button>

可以先把它們分成:

_ViewStart.cshtml
偏向執行設定

_ViewImports.cshtml
偏向匯入設定

真正的畫面內容,還是在一般 View:

Index.cshtml
Create.cshtml
Edit.cshtml
Detail.cshtml

裡面。

為什麼兩支檔案都有底線?

這裡不要看到底線,就以為它們全部都是同一種東西。

例如:

_Layout.cshtml
_ViewStart.cshtml
_ViewImports.cshtml
_Header.cshtml

前面都有 _

但它們的用途完全不同。

可以整理成:

_Layout.cshtml
↓
Layout

_ViewStart.cshtml
↓
View 執行時的共用設定

_ViewImports.cshtml
↓
Razor 共用匯入設定

_Header.cshtml
↓
可能是 Partial View

所以:

都有底線
不代表功能相同

尤其不能看到 _ 就全部把它們當成 Partial View。

_ViewStart.cshtml 可以放很多層嗎?

可以。

這點在比較大的專案裡很容易遇到。

例如:

Views
├── _ViewStart.cshtml
│
└── Admin
    ├── _ViewStart.cshtml
    ├── Index.cshtml
    └── User.cshtml

外層:

Views/_ViewStart.cshtml

可能設定一般 Layout:

@{
    Layout = "_Layout";
}

Admin 裡自己的:

Views/Admin/_ViewStart.cshtml

可能再設定:

@{
    Layout = "_AdminLayout";
}

所以可以先理解成:

外層 _ViewStart.cshtml
↓
先提供比較大的共用設定

進到內層資料夾
↓
還可以再有自己的 _ViewStart.cshtml

↓
依照該區域的需求調整設定

這也是為什麼實際追企業專案時,如果某個 View 的 Layout 看起來怪怪的,不要只搜尋:

Views/_ViewStart.cshtml

還要看目前 View 所在的資料夾階層裡,有沒有其他 _ViewStart.cshtml

_ViewImports.cshtml 也有階層概念嗎?

有。

例如:

Views
├── _ViewImports.cshtml
│
└── Admin
    ├── _ViewImports.cshtml
    └── Index.cshtml

外層可以放很多 View 都需要的共用匯入。

內層也可以再加入只有這個區域需要的設定。

所以如果某個 View 明明沒有:

@using SomeNamespace

卻還是可以直接使用某個類別,也不要只看目前這支 View。

可以往資料夾階層找:

_ViewImports.cshtml

看看是不是已經在其他地方被共用匯入。

實際追專案時,我會怎麼用這兩支檔案?

假設今天打開:

Views/User/Edit.cshtml

裡面看到:

@model EditUserViewModel

但我心裡想:

EditUserViewModel 為什麼不用寫完整 namespace?

這時我就會去找:

_ViewImports.cshtml

看看是不是有:

@using MyProject.ViewModels

但如果我的問題變成:

這個 Edit.cshtml 明明沒有寫 Layout
為什麼畫面還是有 Header 和 Sidebar?

這時就會先找:

_ViewStart.cshtml

看看是不是有:

@{
    Layout = "_Layout";
}

接著再去:

_Layout.cshtml

找 Header、Sidebar 到底寫在哪裡。

所以我現在的追法會變成:

不知道為什麼會套 Layout?
↓
找 _ViewStart.cshtml

不知道某個類別為什麼可以直接使用?
↓
找 _ViewImports.cshtml

不知道 Header、Sidebar 從哪裡來?
↓
從 _ViewStart.cshtml 找到 Layout
↓
再看 _Layout.cshtml 或 Partial View

這樣追就比一開始看到一堆 .cshtml 到處亂點快很多。

如果我要自己建立,最基本怎麼寫?

最小範例可以直接這樣。

Views/_ViewStart.cshtml

@{
    Layout = "_Layout";
}

Views/_ViewImports.cshtml

@using MyProject.ViewModels

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Views/Shared/_Layout.cshtml

<!DOCTYPE html>
<html>

<body>

    <header>
        共用 Header
    </header>

    <main>
        @RenderBody()
    </main>

</body>

</html>

Views/Home/Index.cshtml

@model HomeViewModel

<h1>@Model.Title</h1>

這時幾支檔案的關係就是:

_ViewStart.cshtml
↓
告訴 Index.cshtml 預設使用哪個 Layout

_ViewImports.cshtml
↓
讓 Index.cshtml 可以直接使用 HomeViewModel

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

Index.cshtml
↓
負責首頁自己的內容

所以這幾支檔案不是互不相關。

而是一起參與 View 最後的產生過程。

實際修改時要注意什麼?

_ViewStart.cshtml_ViewImports.cshtml 有一個共同點:

一改
可能同時影響很多 View

例如把:

Layout = "_Layout";

改成:

Layout = "_NewLayout";

可能讓一整群 View 全部換版型。

而如果從 _ViewImports.cshtml 刪掉:

@using MyProject.ViewModels

也可能讓很多 View 同時出現:

找不到型別
找不到 namespace

之類的錯誤。

如果:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

被移除或改錯,也可能影響很多原本使用:

asp-for
asp-action
asp-controller

的 Razor View。

所以修改前我會先確認:

這支 _ViewStart.cshtml 影響哪些 View?

這支 _ViewImports.cshtml 影響哪些 View?

我真的需要改共用設定嗎?

還是只需要修改目前這一頁?

這跟上一篇修改 _Layout.cshtml 的概念很像。

企業專案裡越共用的檔案,修改前越要先確認影響範圍。

這篇先記住什麼?

最簡單的記法就是:

_ViewStart.cshtml
↓
View 執行時的共用設定
↓
最常看到 Layout

例如:

@{
    Layout = "_Layout";
}

而:

_ViewImports.cshtml
↓
View 共用的 Razor 匯入設定
↓
最常看到 @using 和 @addTagHelper

例如:

@using MyProject.ViewModels

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

所以之後看到:

這個 View 明明沒寫 Layout
為什麼還是有 Header?

先找:

_ViewStart.cshtml

看到:

這個 View 明明沒寫 namespace
為什麼可以直接用 ViewModel?

先找:

_ViewImports.cshtml

整體關係可以整理成:

_ViewStart.cshtml
↓
提供 View 執行時的共用設定

_ViewImports.cshtml
↓
提供 Razor 共用匯入

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

一般 View
↓
負責目前頁面的內容

到這裡,我對 Views 資料夾裡那些一堆底線開頭的 .cshtml,終於不會再全部看成同一種東西。

下一篇接著看另外兩個很容易混在一起的東西:

Partial View 和 RenderSection 看起來都像是在把內容拆開,它們實際用途到底差在哪裡?


上一篇
Day 14|`_Layout.cshtml` 是什麼?共用版型和 `@RenderBody()` 怎麼組成完整頁面?
下一篇
Day 16|一個 View 太長怎麼辦?Partial View 和 RenderSection 到底什麼時候用?
系列文
學過一點 React,卻被撈進 C#:新手用 AI 硬啃 MVC 企業專案的 3 個月實錄17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言