_Layout布局(版面配置)页
预设当我们新建好.net5 mvc专案後
比方今天新增一个空的Razor检视
当执行在浏览器呈现时候会发现被套用到一个预设布局页
主要原因在於
.net core mvc预设会产生和之前.net webform MasterPage
有点类似的布局套版页机制
_ViewStart.cshtml
本质也是一个View但主要是跟MasterPage一样的定义布局页(布局视图)
_ViewStart.cshtml会比其他所有视图都还要优先被运行
Layout这里有指定一个名称_Layout代表指向_Layout.cshtml,
而_Layout.cshtml才是真正的布局内容。
专案目录摆放层级
./Views/_ViewStart.cshtml
./Views/Shared/_Layout.cshtml
_Layout.cshtml布局实质前端档案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Net5MvcApp1</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">Net5MvcApp1</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 justify-content-between">
<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">
© 2021 - Net5MvcApp1 - <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>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
当中主要负责变化引入Content页采用@RenderBody()语法
来做套版
假设我们Add.cshtml不想套用布局页
则可以在档案中用Razor语法来指定Layout为null即可
那想自行创建一个布局页
也是可以就在Shared目录下
新建Razor版面配置页(布局),命名通常习惯以下滑线为开头。
预设就会帮我们安插好@RenderBody()
假设这里设置一个简单样式
_Site.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div style="color:red;">
@RenderBody()
</div>
</body>
</html>
在去_ViewStart.cshtml来做全域性更改设置
再去运行即可套用自己设置的版面配置
版面配置页在设置上可以单指定档名,也可指定完整路径。
这里创建额外的版面配置页
./Views/Shared/_SiteLayout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div style="height:50px; width:100%; background-color:blue;color:white;">
<span>SiteLayout测试版面配置</span>
</div>
<div style="height:500px;">
@RenderBody()
</div>
<div style="height: 30px; width: 100%; background-color: red; color: white;">
底部
</div>
</body>
</html>
新增额外一个ProductController.cs,两个action method (Index , Show)
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5MvcApp1.Controllers
{
public class ProductController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Show()
{
return View();
}
}
}
各自都采用默认检视
.\Views\Product\Index.cshtml
单指定档名
@{
Layout = "_SiteLayout";
}
<div>
Product-视图页Index
</div>
.\Views\Product\Show.cshtml
指定完整路径
@{
Layout = "/Views/Shared/_SiteLayout.cshtml";
}
<div>
Product-视图页Show
</div>
运行效果
上面是一个View就指定一次的方式
若今天视图有100个就要重复100次
若不想这麽累可以直接从_ViewStart.cshtml
更改默认全域版面配置(布局)页,之後每页就不需要去设置Layout了。
分布视图、部分检视/PartialView
主要用於某个主视图中的部分内容,常用在部分内容更新。
於Controller当中会使用 PartialView()语法来回传
可返回指定的View或Model Entity,跟View()使用一样。
跟一般的不需要引用布局页。
分布视图的新建
在./Views/Product 目录新建检视(跟一般检视新增方式一样)
return partial view语法
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5MvcApp1.Controllers
{
public class ProductController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Show()
{
return View();
}
public IActionResult Add()
{
return PartialView("_Partial01");
}
}
}
运行效果
没有被套用全域默认版面配置
若在某一个主页面比方Product的Show检视
去加载分布视图
此时可以在检视中使用partial tag来实践
@{
Layout = "/Views/Shared/_SiteLayout.cshtml";
}
<div>
Product-视图页Show
</div>
<div>
<partial name="/Views/Product/_Partial01.cshtml" />
</div>
PartialView的tag写法主要是取代
Html.Partial 、 Html.RenderPartial这两个同步的写法方式
但有时你的分布页可能会需要等待loading这时
会建议改采用非同步处理
也就是不会有上半部没Load完下半部也会Delay
写法也可以换成@await Html.PartialAsync("分布视图路径")
或者@{await Html.RenderPartialAsync("/Views/Product/_Partial01.cshtml");}
以下是程序范本
@{
Layout = "/Views/Shared/_SiteLayout.cshtml";
}
<div>
Product-视图页Show
</div>
<div>
@*第1种.partial tag Tag helper*@
<partial name="/Views/Product/_Partial01.cshtml" />
@* 同步的方式-------*@
@*Html Helper第1种.Html.Partial*@
@Html.Partial("/Views/Product/_Partial01.cshtml")
@*Html Helper第2种.Html.RenderPartial*@
@{
Html.RenderPartial("/Views/Product/_Partial01.cshtml");
}
@* 同步的方式-------*@
@* 非同步的方式-------*@
@*Html Helper第1种.Html.PartialAsync*@
@await Html.PartialAsync("/Views/Product/_Partial01.cshtml")
@*Html Helper第2种.Html.RenderPartialAsync*@
@{
await Html.RenderPartialAsync("/Views/Product/_Partial01.cshtml");
}
@* 非同步的方式-------*@
</div>
<div>
後面的网页内容
</div>
View资料传递
从Controller要传递资料到View基本上跟以前的.net mvc也没有舍麽不同
ASP.NET MVC(六)_ViewData,ViewBag,TempData用法与差异比较
在View内传递值也是可以的
版面配置页跟View之间传递资料方式
比方预设的_Layout中有一个Title的ViewData
在版面配置页有默认值
但是当到了特定单一View
比方Home的Index或是Privacy
就又被客制指定为别的标题文字内容
强类型(型别)视图(大量资料或物件的传递)
在从控制器要传送资料到View过程若只是单纯的string或者数值要传送可以依赖
ViewData , ViewBag
但若需要向VIew传送比较大量的资料或者要有跨server互动作用的资料
则会建议采用强类型(型别)视图机制
一般Model 物件传递方式
在Models目录新增一个Class (模型类别)
命名为BookViewModel
(BookViewModel.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5MvcApp1.Models
{
public class BookViewModel
{
public string Name { get; set; }
public double Price { get; set; }
}
}
建立好Book控制器并撰写程序
BookController.cs
using Microsoft.AspNetCore.Mvc;
using Net5MvcApp1.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5MvcApp1.Controllers
{
public class BookController : Controller
{
public IActionResult Index()
{
List<BookViewModel> bookViewModels = new List<BookViewModel>()
{
new BookViewModel(){Name="外宿族必备宝典:1次搞懂租屋细节",Price=300},
new BookViewModel(){Name="年年18%,一生理财这样做就对了(全新修订版)",Price=380},
new BookViewModel(){Name="无脑理财术,小资大翻身!:无论起薪多少都受用的超简单投资法",Price=320}
};
ViewBag.BookList = bookViewModels;
return View();
}
}
}
与新增预设View後
./Views/Book/Index.cshtml
<table class="table table-bordered">
<tr class="bg-primary">
<td style="color:white">图书名称</td>
<td style="color:white">图书单价</td>
</tr>
@foreach (var item in ViewBag.BookList)
{
<tr>
<td>@item.Name</td>
<td>@item.Price</td>
</tr>
}
</table>
运行结果即可看到
透过ViewBag将dynamic书单列表呈现在View中
但当栏位一多的时候这种方式可能比较不方便没有智能提示容易打错
因此也可以透过IEnumerable的泛型来做传递,在遍历Book Model的时候
就能有智能提示对应属性
<table class="table table-bordered">
<tr class="bg-primary">
<td style="color:white">图书名称</td>
<td style="color:white">图书单价</td>
</tr>
@foreach (var item in ViewBag.BookList as IEnumerable<Net5MvcApp1.Models.BookViewModel>)
{
<tr>
<td>@item.Name</td>
<td>@item.Price</td>
</tr>
}
</table>
但可能仍有一些美中不足
我们不想每次在IEnumerable里面都要把整个命名空间写进来有点太长
在View里面当然也可省略命名空间
可以省略主因在於.net core MVC中有提供一个导入文件
./Views/_ViewImports.cshtml
里面自动引入该name space
强类型(型别)视图传递方式
不透过ViewData或ViewBag这些不确定的型别(泛型列表)
而是采用具体的Class型态(强型别)在控制器和视图之间做资料传递互动,将Model跟View结合起来组成的View就称为强类型(型别)视图。
於Controller直接透过 return View(某型别物件(集合) )回传,也就是给ViewData中的Model赋值。
於View当中可以用List<某型别物件> 或IEnumerable<某型别物件>方式遍历
强型别传入模型的BookController.cs
using Microsoft.AspNetCore.Mvc;
using Net5MvcApp1.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5MvcApp1.Controllers
{
public class BookController : Controller
{
public IActionResult Index()
{
List<BookViewModel> bookViewModels = new List<BookViewModel>()
{
new BookViewModel(){Name="外宿族必备宝典:1次搞懂租屋细节",Price=300},
new BookViewModel(){Name="年年18%,一生理财这样做就对了(全新修订版)",Price=380},
new BookViewModel(){Name="无脑理财术,小资大翻身!:无论起薪多少都受用的超简单投资法",Price=320}
};
//ViewBag.BookList = bookViewModels;
return View(bookViewModels);
}
}
}
强型别视图访问的View(./Views/Book/Index.cshtml)
<table class="table table-bordered">
<tr class="bg-primary">
<td style="color:white">图书名称</td>
<td style="color:white">图书单价</td>
</tr>
@model List<BookViewModel>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Price</td>
</tr>
}
</table>
在.net core mvc当中的razor语法则跟之前.net mvc是一样的
ASP.NET MVC(五)_Razor语法笔记
就不再多赘述
本篇同步发表至个人部落格
https://coolmandiary.blogspot.com/2021/07/net-core13viewlayout.html
Ref:
The Partial Tag Helper
https://www.learnrazorpages.com/razor-pages/tag-helpers/partial-tag-helper
5 ways to render a partial view in asp.net core
https://nitishkaushik.com/how-to-render-a-partial-view-in-asp-net-core/
>>: 【Day3】[资料结构]-链结串列Linked List
以下内容皆参考 Backtrader 官网 在评估股票的时候,我们常常会用一些指标来辅助,今天来介绍...
前言 当我们终於准备上架 Google Play,我们需要决定在哪些国家、年龄层、装置等才能够看到我...
当一个模型的训练资料和测试资料,彼此之间的资料分布有不匹配(mismatch)时,模 型的性能会出现...
加以控管 vs. 给予资讯 控管式 老板核准及指挥所有提案 行动和团队决策 有时候会直接监督 来控制...
既然是第一天,不免俗的还是要来自我介绍跟前言一下XD 欢迎来到 30 天我与 Vue 的那些二三事。...