0. 前言

在之前的4篇的内容里,我们较为详细的介绍了路由以及控制器还有视图之间的关系。也就是说,系统如何从用户的HTTP请求解析到控制器里,然后在控制器里处理数据,并返回给视图,在视图中显示出来。这一篇我将为大家介绍基础的最后一部分,布局页和静态资源引入。

1. 布局页

在控制器和视图那一篇,我们了解到_ViewStart 里设置了一个Layout属性的值,这个值正是用来设置布局页的。所谓的布局页,就是视图的公用代码。在实际开发中,布局页通常存放我们为整个系统定义的页面框架,视图里写每个视图的页面。

回顾一下,默认的_ViewStart里的内容是:

@{Layout = "_Layout";
}

默认的布局页指定的是名为_Layout的布局页,在本系列第三篇中,我们得知这个视图应当在Shared文件夹下,那我们进去看一下这个视图有什么内容:

<!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">&copy; 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>

这是默认的布局页内容,看着挺多的,但是除了一些html代码,里面还有一些关键的地方需要注意。

1.1 RenderSection

RenderSection 分部渲染,在页面中创建一个标记,表示这个页面块将在子视图(或者是路由的实际渲染视图)中添加内容。

来,我们看一下微软官方给的注释:

In layout pages, renders the content of the section named name.

意思就是在布局页中,渲染名称为name的分部内容。

新创建一个分布页,名称为_Layout1

<html><head><title>Render 测试</title></head><body>@RenderSection("SectionDemo")</body>
</html>

这个布局页里什么都没有,只有一个RenderSection。现在我们新建一个控制器:

using Microsoft.AspNetCore.Mvc;namespace MvcWeb.Controllers
{public class RenderTestController : Controller{public IActionResult Index(){return View();}}
}

创建对应的视图:

Views / RenderTest/Index.cshtml

先设置布局页为_Layout1

@{Layout = "_Layout1";
}

先试试启动应用,访问:

http://localhost:5006/RenderTest/Index

正常情况下,你应该能看到这个页面:

仔细看一下信息,意思是在 RenderTest/Index.cshtml 视图中没有找到 SectionDemo 的分部内容。

那么,如何在视图中设置分部内容呢?

@{Layout = "_Layout1";
}
@section SectionDemo{<h1>你好</h1>}

使用 @section <Section 名称> 后面跟一对大括号,在大括号中间的内容就是这个section(分部)的内容。

重启应用,然后刷新页面,你能看到这样的页面:

如果不做特殊要求的话,定义在布局页中的分部块,视图必须实现。当然,RenderSection还有一个参数,可以用来设置分部不是必须的:

public HtmlString RenderSection(string name, bool required);

1.2 RenderBody

先看下微软给的官方注释:

In a Razor layout page, renders the portion of a content page that is not within a named section.

简单讲,如果在布局页中设置了@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>我是视图的内容!</h1>

重启应用,刷新刚刚访问的页面:

可以看出,RenderBody渲染的位置。

2. 静态资源引入

通常情况下,静态资源的引入与HTML引用js和css等资源是一致的,但是对于我们在编写系统时自己创建的脚本和样式表,asp.net core提供了不同的处理方式。那就是服务器端压缩功能。

asp.net core 3.0 的mvc 默认项目是不启动这个功能的,需要我们额外的开启支持。

2.1 开启支持

先引入 BuildBundleMinifier

cd MvcWeb # 切换目录到MvcWeb项目下
dotnet add package BuildBundleMinifier

创建 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}
]

每个节点允许设置项:

  • outputFileName 生成的捆绑压缩文件,通常路径携带wwwroot
  • inputFiles 数组,包含要压缩到此次输出文件的文件路径,会按照添加的顺序依次加入
  • minify 输出类型的缩小选项,可选。 默认是 enabled: true
  • sourceMap 表示是否为捆绑的文件生成源映射的标记
  • sourceMapRootPath 源映射文件的路径

2.2 使用

正常情况下在布局页中,把压缩后的文件路径引入即可。不过在开发中,通常按照以下方式引用:

<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静态资源缓存的问题的一个解决方案,这一步是由程序决定的。

environment表示环境,现在大家知道这个写法就行,在接下来的篇幅会讲。

3. 静态资源目录

我们知道到目前为止,我们的静态资源都是在wwwroot目录下。那么我们是否可以修改或者添加别的目录作为静态资源目录呢?

在Startup.cs文件内的Configure方法下有这样一行代码:

app.UseStaticFiles();

这行代码的意思就是启用静态文件,程序自动从 wwwroot寻找资源。那么,我们就可以从这个方法入手,设置我们自己的静态资源:

public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options);

我们找到了这个方法的另一个重载版本,里面有一个参数类:

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; }
}

并没有发现我们想要的,先别慌,它还有个父类。我们再去它的父类里看看:

public abstract class SharedOptionsBase
{protected SharedOptionsBase(SharedOptions sharedOptions);public IFileProvider FileProvider { get; set; }public PathString RequestPath { get; set; }protected SharedOptions SharedOptions { get; }
}

这下就比较明了了,需要我们提供一个文件提供器,那么我们来找一个合适的IFileProvider实现类吧:

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")),});
}

在项目的根目录创建名为OtherStatic的文件夹,然后在里面创建个文件夹,例如: files,并在这个文件夹里随便添加一个文件。

然后启动应用访问:

http://localhost:5006/files/<你添加的文件(包括后缀名)>

然后能在浏览器中看到这个文件被正确响应。

当然,这里存在一个问题,如果在 OtherStatic中的文件在wwwroot也有相同目录结构的文件存在,这样访问就会出现问题。这时候,可以为我们新加的这个配置设置一个请求前缀:

app.UseStaticFiles(new StaticFileOptions
{FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),"OtherStatic")),RequestPath = "/other"
});

重启程序,然后访问:

http://localhost:5006/other/files/<你添加的文件(包括后缀名)>

然后就能看到刚才响应的文件,重新访问之前的路径,发现浏览器提示404。

4. 总结

在这一篇,我们讲解了布局页的内容,静态资源的压缩绑定以及添加一个新的静态资源目录。通过这几篇内容,让我们对asp.net core mvc有了一个基本的认知。下一篇,我们将重新创建一个项目,并结合之前的内容,以实战为背景,带领大家完成一个功能完备的web系统。

更多内容烦请关注我的博客《高先生小屋》

【asp.net core 系列】5 布局页和静态资源相关推荐

  1. .ne中的控制器循环出来的数据如何显示在视图上_【asp.net core 系列】3 视图以及视图与控制器...

    0.前言 在之前的几篇中,我们大概介绍了如何创建一个http://asp.net core mvc项目以及http请求如何被路由转交给对应的执行单元.这一篇我们将介绍一下控制器与视图直接的关系. 1. ...

  2. asp.net core系列 40 Web 应用MVC 介绍与详细示例

    一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...

  3. asp.net core系列 38 WebAPI 返回类型与响应格式--必备

    一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...

  4. asp.net core系列 67 Web压力测试工具WCAT

    asp.net core系列 67 Web压力测试工具WCAT 原文:asp.net core系列 67 Web压力测试工具WCAT 一.介绍 最近搭建了一套CQRS框架,需要在投入开发前,进行必要的 ...

  5. ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门 1

    ASP.NET Core 入门教程 6.ASP.NET Core MVC 视图布局入门 原文:ASP.NET Core 入门教程 6.ASP.NET Core MVC 视图布局入门 一.前言 1.本教 ...

  6. 5.3Role和Claims授权「深入浅出ASP.NET Core系列」

    5.3Role和Claims授权「深入浅出ASP.NET Core系列」 原文:5.3Role和Claims授权「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁. ...

  7. 4.1ASP.NET Core请求过程「深入浅出ASP.NET Core系列」

    原文:4.1ASP.NET Core请求过程「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. HTTP请求过程 这里展示整 ...

  8. 5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」

    原文:5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」 希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢 ...

  9. ASP.NET CORE系列【一】搭建ASP.NET CORE项目

    原文:ASP.NET CORE系列[一]搭建ASP.NET CORE项目 为什么要使用 ASP.NET Core? NET Core 刚发布的时候根据介绍就有点心里痒痒,微软的尿性都懂的,新东西bug ...

最新文章

  1. nUnit,凑合着测试
  2. 轻松解决Windows7声卡驱动不全问题
  3. 第18章 类加载机制与反射
  4. IPv6推进将非常漫长
  5. hdu 1692(枚举+剪枝)
  6. VTK:Utilities之GetDataRoot
  7. android--系统jar包引用
  8. 简化工作——我的bat文件
  9. http发送jsonn报文get/post请求
  10. 用资源管理器右键编译 Visual Studio 解决方案文件
  11. SharePoint 2007 在Windows Server 2008上列表Open with Windows Explorer失效 解决
  12. mm和mmm编译说明
  13. 30. 确保目标空间足够大
  14. 时间序列--平稳性介绍及检验方法
  15. 教程,word导出为pdf既要书签和链接又要高清图片
  16. OA升级及二次开发方案
  17. 全市场等权中位数_市场指数估值周报20200406
  18. 信息系统项目管理师必背核心考点(十)信息系统规划
  19. html给文字添加下划线
  20. stacking集成模型预测回归问题

热门文章

  1. 网络代理服务器的设计与实现
  2. 卷妹的成长日记之javaweb day2
  3. 推特情感分析-基于spark
  4. 联想电脑拯救者y7000触摸屏失灵的修复方法
  5. 手机wps怎么设置打印横竖_手机WPS怎么设置横版打印?
  6. 数据库里这是怎么回事啊?
  7. QQ邮箱每次可以群发多少人呢?探秘邮箱最多可以群发多少人?
  8. 微信播放在服务器视频无法播放音乐,【bug解决】ios微信浏览器中背景音乐无法播放...
  9. vulnstack_ATTCK1渗透
  10. MPC5744P-CAN模块