本章我們新建一個項目,並通過這個項目熟悉一下_Layout與_ViewStart以及它們的載入順序. 新建一個項目 首先, 文件->新建一個解決方案 選擇.Net Core 的APP下麵的ASP.NET Core Web App(MVC) Next 設置解決方案的名稱(和Xcode的界面風格有點像) ...
本章我們新建一個項目,並通過這個項目熟悉一下_Layout與_ViewStart以及它們的載入順序.
新建一個項目
首先, 文件->新建一個解決方案
選擇.Net Core 的APP下麵的ASP.NET Core Web App(MVC)
Next
設置解決方案的名稱(和Xcode的界面風格有點像), 輸入FL.WeightManager, 做一個每天記錄體重的應用
點擊Create.
項目新建完畢, 項目的文件結構上一章已經說過了.
_layout的應用
新建好的項目預設運行效果如下圖
頁面主要分三部分, 上面的header, 下麵的footer, 點擊上面菜單總的Home、About和Contact切換一下頁面看一下
這兩部分都是不變的, 只有中間部分在變.
打開Shared文件夾下麵的_layout.cshtml頁面看一下, header和footer都是定義在這裡的,
而中間變的部分是 @RenderBody().也就是我們經常要改變的地方了.
現在將主頁改變一下, 打開Home文件夾下的Index文件,將裡面的一大堆代碼改成如下代碼
1 @{ 2 ViewData["Title"] = "主頁"; 3 } 4 <table class="table table-hover"> 5 <thead> 6 <tr> 7 <th>序號</th> 8 <th>日期</th> 9 <th>體重</th> 10 <th>備註</th> 11 </tr> 12 </thead> 13 <tbody> 14 <tr> 15 <td>1</td> 16 <td>2018-02-15</td> 17 <td>66.6</td> 18 <td>除夕,胖了</td> 19 </tr> 20 <tr> 21 <td>2</td> 22 <td>2018-02-16</td> 23 <td>68.8</td> 24 <td>春節,又重了</td> 25 </tr> 26 </tbody> 27 </table>
刷新一下頁面
看起來效果還不錯, 可能會註意到, 這個table有個class <table class="table table-hover"> ,
這個class定義在哪裡呢.
再次打開_layout文件, 可以看到裡面在Development環境下引用了bootstrap的css
<environment include="Development"> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> <link rel="stylesheet" href="~/css/site.css" /> </environment>
所以可以把一些"通用"的css和js的引用放在layout文件里, 避免重覆寫這些引用.
順便把header和footer中顯示的項目名稱改一下, 然後分別打開Index和About這些頁面, Header和Footer都統一改變了.
如下圖的About頁面.
但是我們在這個Index頁中沒有對這個模板做引用, 是通過什麼方式引用的呢?
_ViewStart的應用
回顧修改後的Index頁面, 我們並沒有寫 Layout = "_Layout" 這樣的代碼, 這是因為已經在_ViewStart中預設設置了
_ViewStart中只有這一句
@{ Layout = "_Layout"; }
如果我們在Index頁面中添加一句 Layout=null 如下,
@{ Layout=null; ViewData["Title"] = "主頁"; }
再次刷新頁面, 樣子變成了這樣
Header和Footer以及Table的樣式全都沒有了, 是因為這些本來都寫在_Layout中, 現在失去了對_Layout的引用, 這些也就消失了.
總結: _ViewStart對模板頁做了預設的設置, 除非顯示的寫明Layout=XXX, 否則會採用_ViewStart中的設置.
所以未做設置和設置 Layout = "_Layout" 的效果是一樣的.
_ViewStart、_Layout和Index(實際頁面)的載入順序
載入順序是: _ViewStart =>Index=>_Layout.
1._ViewStart在所有View載入之前載入, 設置了預設的模板頁.
2.接著由Controller指定的頁面查找Index.cshtml載入, 並讀取該頁面的Layout設置.
3.根據Index頁面的Layout設置的模板頁查找對應的模板頁載入.
將_ViewStart中的 Layout = "_Layout" 改為 Layout = "_Layout1" , 再次運行, 頁面會出現如下找不到模板的錯誤.
An unhandled exception occurred while processing the request. InvalidOperationException: The layout view '_Layout1' could not be located. The following locations were searched: /Views/Home/_Layout1.cshtml /Views/Shared/_Layout1.cshtml Microsoft.AspNetCore.Mvc.Razor.RazorView.GetLayoutPage(ViewContext context, string executingFilePath, string layoutPath)
View的查找規則: 先查找Controller對應的文件夾(這裡是Home), 若未找到則到Shared文件夾查找, 若最終未找到則提示錯誤.