在之前的4篇的內(nèi)容里,我們較為詳細(xì)的介紹了路由以及控制器還有視圖之間的關(guān)系。也就是說,系統(tǒng)如何從用戶的HTTP請求解析到控制器里,然后在控制器里處理數(shù)據(jù),并返回給視圖,在視圖中顯示出來。這一篇我將為大家介紹基礎(chǔ)的最后一部分,布局頁和靜態(tài)資源引入。
在控制器和視圖那一篇,我們了解到_ViewStart 里設(shè)置了一個Layout屬性的值,這個值正是用來設(shè)置布局頁的。所謂的布局頁,就是視圖的公用代碼。在實際開發(fā)中,布局頁通常存放我們?yōu)檎麄€系統(tǒng)定義的頁面框架,視圖里寫每個視圖的頁面。
回顧一下,默認(rèn)的_ViewStart里的內(nèi)容是:
@{
Layout="_Layout";
}
默認(rèn)的布局頁指定的是名為_Layout的布局頁,在本系列第三篇中,我們得知這個視圖應(yīng)當(dāng)在Shared文件夾下,那我們進(jìn)去看一下這個視圖有什么內(nèi)容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MvcWeb</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcWeb</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
? 2020 - MvcWeb - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
這是默認(rèn)的布局頁內(nèi)容,看著挺多的,但是除了一些html代碼,里面還有一些關(guān)鍵的地方需要注意。
RenderSection 分部渲染,在頁面中創(chuàng)建一個標(biāo)記,表示這個頁面塊將在子視圖(或者是路由的實際渲染視圖)中添加內(nèi)容。
來,我們看一下微軟官方給的注釋:
In layout pages, renders the content of the section named name.
意思就是在布局頁中,渲染名稱為name的分部內(nèi)容。
新創(chuàng)建一個分布頁,名稱為_Layout1:
<html>
<head>
<title>Render 測試</title>
</head>
<body>
@RenderSection("SectionDemo")
</body>
</html>
這個布局頁里什么都沒有,只有一個RenderSection。現(xiàn)在我們新建一個控制器:
using Microsoft.AspNetCore.Mvc;
namespace MvcWeb.Controllers
{
public class RenderTestController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
創(chuàng)建對應(yīng)的視圖:
Views / RenderTest/Index.cshtml
先設(shè)置布局頁為_Layout1:
@{
Layout="_Layout1";
}
先試試啟動應(yīng)用,訪問:
http://localhost:5006/RenderTest/Index
正常情況下,你應(yīng)該能看到這個頁面:
仔細(xì)看一下信息,意思是在 RenderTest/Index.cshtml 視圖中沒有找到 SectionDemo 的分部內(nèi)容。
那么,如何在視圖中設(shè)置分部內(nèi)容呢?
@{
Layout="_Layout1";
}
@section SectionDemo{
<h1>你好</h1>
}
使用 @section <Section 名稱> 后面跟一對大括號,在大括號中間的內(nèi)容就是這個section(分部)的內(nèi)容。
重啟應(yīng)用,然后刷新頁面,你能看到這樣的頁面:
如果不做特殊要求的話,定義在布局頁中的分部塊,視圖必須實現(xiàn)。當(dāng)然,RenderSection還有一個參數(shù),可以用來設(shè)置分部不是必須的:
public HtmlString RenderSection(string name, bool required);
先看下微軟給的官方注釋:
In a Razor layout page, renders the portion of a content page that is not within a named section.
簡單講,如果在布局頁中設(shè)置了@RenderBody,那么在使用了這個布局頁的視圖里所有沒被分部塊包裹的代碼都會渲染到布局頁中聲明了@RenderBody的地方。
修改_Layout1.cshtml:
<html>
<head>
<title>Render 測試</title>
</head>
<body>
<h1>RenderBody 測試 -之前</h1>
@RenderBody()
<h1>RenderBody 測試 -之后</h1>
</body>
</html>
修改RenderTest/Index.cshtml:
@{
Layout="_Layout1";
}
RenderBody測試
<h1>我是視圖的內(nèi)容!</h1>
重啟應(yīng)用,刷新剛剛訪問的頁面:
可以看出,RenderBody渲染的位置。
通常情況下,靜態(tài)資源的引入與HTML引用js和css等資源是一致的,但是對于我們在編寫系統(tǒng)時自己創(chuàng)建的腳本和樣式表,asp.net core提供了不同的處理方式。那就是服務(wù)器端壓縮功能。
asp.net core 3.0 的mvc 默認(rèn)項目是不啟動這個功能的,需要我們額外的開啟支持。
先引入 BuildBundleMinifier
cd MvcWeb # 切換目錄到MvcWeb項目下
dotnet add package BuildBundleMinifier
創(chuàng)建 bundleconfig.json
[
{
"outputFileName": "wwwroot/css/site.min.css",
"inputFiles": [
"wwwroot/css/site.css"
]
},
{
"outputFileName": "wwwroot/js/site.min.js",
"inputFiles": [
"wwwroot/js/site.js"
],
"minify": {
"enabled": true,
"renameLocals": true
},
"sourceMap": false
}
]
每個節(jié)點允許設(shè)置項:
正常情況下在布局頁中,把壓縮后的文件路徑引入即可。不過在開發(fā)中,通常按照以下方式引用:
<environment exclude="Development">
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
<environment include="Development">
<link rel="stylesheet" href="~/css/site.css" />
</environment>
注: asp-append-version 表示在引用路徑追加一個版本號,這是針對html靜態(tài)資源緩存的問題的一個解決方案,這一步是由程序決定的。
environment表示環(huán)境,現(xiàn)在大家知道這個寫法就行,在接下來的篇幅會講。
我們知道到目前為止,我們的靜態(tài)資源都是在wwwroot目錄下。那么我們是否可以修改或者添加別的目錄作為靜態(tài)資源目錄呢?
在Startup.cs文件內(nèi)的Configure方法下有這樣一行代碼:
app.UseStaticFiles();
這行代碼的意思就是啟用靜態(tài)文件,程序自動從 wwwroot尋找資源。那么,我們就可以從這個方法入手,設(shè)置我們自己的靜態(tài)資源:
public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options);
我們找到了這個方法的另一個重載版本,里面有一個參數(shù)類:
public class StaticFileOptions : SharedOptionsBase
{
public StaticFileOptions();
public StaticFileOptions(SharedOptions sharedOptions);
public IContentTypeProvider ContentTypeProvider { get; set; }
public string DefaultContentType { get; set; }
public HttpsCompressionMode HttpsCompression { get; set; }
public Action<StaticFileResponseContext> OnPrepareResponse { get; set; }
public bool ServeUnknownFileTypes { get; set; }
}
并沒有發(fā)現(xiàn)我們想要的,先別慌,它還有個父類。我們再去它的父類里看看:
public abstract class SharedOptionsBase
{
protected SharedOptionsBase(SharedOptions sharedOptions);
public IFileProvider FileProvider { get; set; }
public PathString RequestPath { get; set; }
protected SharedOptions SharedOptions { get; }
}
這下就比較明了了,需要我們提供一個文件提供器,那么我們來找一個合適的IFileProvider實現(xiàn)類吧:
public class PhysicalFileProvider : IFileProvider, IDisposable
這個類可以滿足我們的要求,它位于命名空間:
namespace Microsoft.Extensions.FileProviders
那么,添加一組我們自己的配置吧:
using Microsoft.Extensions.FileProviders;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 省略其他代碼,僅添加以下代碼
app.UseStaticFiles(new StaticFileOptions
{
FileProvider=new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),"OtherStatic")),
});
}
在項目的根目錄創(chuàng)建名為OtherStatic的文件夾,然后在里面創(chuàng)建個文件夾,例如: files,并在這個文件夾里隨便添加一個文件。
然后啟動應(yīng)用訪問:
http://localhost:5006/files/<你添加的文件(包括后綴名)>
然后能在瀏覽器中看到這個文件被正確響應(yīng)。
當(dāng)然,這里存在一個問題,如果在 OtherStatic中的文件在wwwroot也有相同目錄結(jié)構(gòu)的文件存在,這樣訪問就會出現(xiàn)問題。這時候,可以為我們新加的這個配置設(shè)置一個請求前綴:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider=new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),"OtherStatic")),
RequestPath="/other"
});
重啟程序,然后訪問:
http://localhost:5006/other/files/<你添加的文件(包括后綴名)>
然后就能看到剛才響應(yīng)的文件,重新訪問之前的路徑,發(fā)現(xiàn)瀏覽器提示404。
在這一篇,我們講解了布局頁的內(nèi)容,靜態(tài)資源的壓縮綁定以及添加一個新的靜態(tài)資源目錄。通過這幾篇內(nèi)容,讓我們對asp.net core mvc有了一個基本的認(rèn)知。下一篇,我們將重新創(chuàng)建一個項目,并結(jié)合之前的內(nèi)容,以實戰(zhàn)為背景,帶領(lǐng)大家完成一個功能完備的web系統(tǒng)。
求關(guān)注,求點贊,求轉(zhuǎn)發(fā)~~有啥可以評論喲
4 種方式可以在 HTML 中引入 CSS。其中有 2 種方式是在 HTML 文件中直接添加 CSS 代碼,另外兩種是引入 外部 CSS 文件。下面我們就來看看這些方式和它們的優(yōu)缺點。
內(nèi)聯(lián)方式
內(nèi)聯(lián)方式指的是直接在 HTML 標(biāo)簽中的 style 屬性中添加 CSS。
示例:
<div style="background: red"></div>
這通常是個很糟糕的書寫方式,它只能改變當(dāng)前標(biāo)簽的樣式,如果想要多個 <div> 擁有相同的樣式,你不得不重復(fù)地為每個 <div> 添加相同的樣式,如果想要修改一種樣式,又不得不修改所有的 style 中的代碼。很顯然,內(nèi)聯(lián)方式引入 CSS 代碼會導(dǎo)致 HTML 代碼變得冗長,且使得網(wǎng)頁難以維護(hù)。
嵌入方式
嵌入方式指的是在 HTML 頭部中的 <style> 標(biāo)簽下書寫 CSS 代碼。
示例:
<head> <style> .content { background: red; } </style> </head>
嵌入方式的 CSS 只對當(dāng)前的網(wǎng)頁有效。因為 CSS 代碼是在 HTML 文件中,所以會使得代碼比較集中,當(dāng)我們寫模板網(wǎng)頁時這通常比較有利。因為查看模板代碼的人可以一目了然地查看 HTML 結(jié)構(gòu)和 CSS 樣式。因為嵌入的 CSS 只對當(dāng)前頁面有效,所以當(dāng)多個頁面需要引入相同的 CSS 代碼時,這樣寫會導(dǎo)致代碼冗余,也不利于維護(hù)。
鏈接方式
鏈接方式指的是使用 HTML 頭部的 <head> 標(biāo)簽引入外部的 CSS 文件。
示例:
<head> <link rel="stylesheet" type="text/css" href="style.css"> </head>
這是最常見的也是最推薦的引入 CSS 的方式。使用這種方式,所有的 CSS 代碼只存在于單獨的 CSS 文件中,所以具有良好的可維護(hù)性。并且所有的 CSS 代碼只存在于 CSS 文件中,CSS 文件會在第一次加載時引入,以后切換頁面時只需加載 HTML 文件即可。
導(dǎo)入方式
導(dǎo)入方式指的是使用 CSS 規(guī)則引入外部 CSS 文件。
示例:
<style> @import url(style.css); </style>
比較鏈接方式和導(dǎo)入方式
鏈接方式(下面用 link 代替)和導(dǎo)入方式(下面用 @import 代替)都是引入外部的 CSS 文件的方式,下面我們來比較這兩種方式,并且說明為什么不推薦使用 @import。
小結(jié):我們應(yīng)盡量使用 <link> 標(biāo)簽導(dǎo)入外部 CSS 文件,避免或者少用使用其他三種方式。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。