ASP.NET Core MVC 快速製作麵包屑導覽 Breadcrumb 教學

麵包屑是什麼?

什麼是麵包屑 (Breadcrumb)? 依據維基百科的說明,他是使用者介面的一種導覽輔助,讓使用者方便確認和跳轉所在頁面位置的功能,麵包屑這個詞來自於糖果屋童話故事,在故事中就是依照麵包屑找到回家的路。

在 Bootstrap 中麵包屑的樣式如下:

在上面的範例中假設當前頁面為 Home (第一行),則只顯示文字,如果當前頁面在 Library (第二行),則 Library 只顯示文字,而他的上層目錄 Home 為連結,使用者可以點擊連結回到 Home 頁面。
註: Bootstrap 並未在上面的範例中加上實際連結

在 ASP.NET Core 7 MVC 中似乎沒有簡易的方式可以建立麵包屑,不過還好有萬能的網友製作的套件 - SmartBreadcrumbs,雖然在筆者撰文當下(2022/12/11)的上次更新是在兩年前(2020/11/7),不過除了說明文件以外其他的部分在 .NET 7 中都能正常運作

安裝 SmartBreadcrumbs 套件

先使用 NuGet 安裝 SmartBreadcrumbs 套件,或是使用 .NET CLI 執行以下指令安裝
	
dotnet add package SmartBreadcrumbs
    

在 Program.cs 中增加下面指令以啟用套件

builder.Services.AddBreadcrumbs(Assembly.GetExecutingAssembly());
    

如果想要自訂麵包屑樣式可以在這時候調整,筆者以 ASP.NET Core MVC 預設使用的 Bootstrap 的麵包屑樣式做基本設定範例:

builder.Services.AddBreadcrumbs(Assembly.GetExecutingAssembly(), options =>
{
    options.TagName = "nav";
    options.TagClasses = "";
    options.OlClasses = "breadcrumb";
    options.LiClasses = "breadcrumb-item text-sm";
    options.ActiveLiClasses = "breadcrumb-item text-sm";
});
    

引用 SmartBreadcrumbs

因為我們想要在全部的頁面中使用到,所以直接加在 Views/_ViewImports.cshtml ,讓所有頁面都可以自動引用 SmartBreadcrumbs
    

@addTagHelper *, SmartBreadcrumbs
    

顯示麵包屑

在要顯示的位置加入 breadcrumb 這個 HTML Tag 即可,本次範例我們在所有地方都會顯示,於是就加在 Views/Shared/_Layout.cshtml 中
    

<div class="container">
	<breadcrumb></breadcrumb>
	<main role="main" class="pb-3">
		@RenderBody()
	</main>
</div>
    

此時若直接執行會拋出下列錯誤:
    
dotnet watch 🚀 Started
Unhandled exception. System.InvalidOperationException: Sequence contains no matching element
   at System.Linq.ThrowHelper.ThrowNoMatchException()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
   at SmartBreadcrumbs.BreadcrumbManager.GenerateHierarchy(Dictionary`2 entries)
   at SmartBreadcrumbs.BreadcrumbManager.Initialize(Assembly assembly)
   at SmartBreadcrumbs.Extensions.ServiceCollectionExtensions.AddBreadcrumbs(IServiceCollection services, Assembly assembly, BreadcrumbOptions options)
   at SmartBreadcrumbs.Extensions.ServiceCollectionExtensions.AddBreadcrumbs(IServiceCollection services, Assembly assembly, Action`1 optionsSetter)
   at Program.<Main>$(String[] args) in C:\Users\ruyut\Documents\RiderProjects\test\2022\WebApplicationMvcBreadcrumbTest\WebApplicationMvcBreadcrumbTest\Program.cs:line 19
       

原因是還沒設定麵包屑的內容,等等設定完後就可以正常執行了。

設定預設麵包屑

將預設麵包屑路徑綁在網站首頁,這裡我們將 DefaultBreadcrumb 這個註解(Attribute)加在 HomeController 中 Index 的 Action 上面,除了 Action 外該註解(Attribute)也可以綁在 Razor Page 或是 MVC Controller 上
    
    
public class HomeController : Controller
{
    [DefaultBreadcrumb("首頁")]
    public IActionResult Index()
    {
        return View();
    }
}


自訂麵包屑內容

我們建立一個示範用的 StudentController ,在 Action 上面使用 Breadcrumb 註解(Attribute)來標記當前 Action 頁面在麵包屑上要顯示的名稱,FromAction 屬性為上一層的 Action,FromController 屬性為上一層的 Controller,若為同層級可以省略(本示範中 Create Action 上的 "FromController = typeof(StudentController)" 就可以省略)
    
    
public class StudentController : Controller
{
    // 麵包屑: 首頁 / 學生
    [Breadcrumb("學生")]
    public IActionResult Index()
    {
        return View();
    }

    // 麵包屑: 首頁 / 學生 / 清單
    [Breadcrumb("清單")]
    public IActionResult List()
    {
        return View();
    }

    // 麵包屑: 首頁 / 學生 / 清單 / 新增
    [Breadcrumb("新增", FromAction = nameof(List), FromController = typeof(StudentController))]
    public IActionResult Create()
    {
        return View();
    }
}

在上面的程式碼中因為一開始有放置 DefaultBreadcrumb ,所以麵包屑第一層就是一開始加上的「首頁」,而因為預設規則是 Index 是 Controller 的預設頁面,所以會自動將 Index 的麵包屑加上去,如果不想要加上 Index 這層的話可以手動指向 DefaultBreadcrumb 的 Action 即可(在本例中是 HomeController 的 Index)。
而 Create 則是因為我們指向 List ,所以上一層才會是「清單」,不然應該不會存在「清單」這一層

畫面效果:



參考資料:
Github - SmartBreadcrumbs
套件作者部落格 - Managing breadcrumbs in ASP.NET core using SmartBreadcrumbs

留言