1 起个头
很多95后的程序员没有搞明白MVC,需要多练习才行。
MVC实际上不是设计模式,而是架构模式/体系结构模式,体系结构是老称呼了,现在基本上都叫架构了。
模型-视图-控制器 (MVC) 体系结构模式将应用分成 3 个主要组件:模型 (M)、视图 (V) 和控制器 (C)。 MVC 模式有助于创建比传统单片应用更易于测试和更新的应用。
模型 (M):表示应用数据的类。 模型类使用验证逻辑来对该数据强制实施业务规则。 通常,模型对象检索模型状态并将其存储在数据库中。
视图 (V):视图是显示应用用户界面 (UI) 的组件。 此 UI 通常会显示模型数据。
控制器 (C):处理浏览器请求的类。 它们检索模型数据并调用返回响应的视图模板。 在 MVC 应用中,视图仅显示信息;控制器处理并响应用户输入和交互。 例如,控制器处理路由数据和查询字符串值,并将这些值传递给模型。 该模型可使用这些值查询数据库。
1.1 MVC优点
l MVC 模式可帮助创建分隔不同应用特性(输入逻辑、业务逻辑和 UI 逻辑)的应用,同时让这些元素之间实现松散耦合。
l 该模式可指定应用中每种逻辑的位置。 UI 逻辑位于视图中。 输入逻辑位于控制器中。 业务逻辑位于模型中。
l 这种隔离有助于控制构建应用时的复杂程度,因为它可用于一次处理一个实现特性,而不影响其他特性的代码。 例如,处理视图代码时不必依赖业务逻辑代码
1.2 创建一个MVC项目
1.3 新增一个控制器
1.4 新增HTTP终结点调用
控制器中的每个 public 方法均可作为 HTTP 终结点调用。
HTTP 终结点是 Web 应用程序中可定向的 URL(例如 https://localhost:44399/EdisonTest ),其中结合了所用的协议HTTPS 、TCP 端口等 Web 服务器的网络位置 localhost:44399 ,以及目标 URI EdisonTest。
2 进一步
2.1 路由
MVC 根据入站 URL 调用控制器类(及其中的操作方法)。 MVC 所用的默认 URL 路由逻辑使用如下格式来确定调用的代码:
/[Controller]/[ActionName]/[Parameters]
在 Startup.cs 文件的 Configure 方法中设置路由格式。
如果浏览到应用且不提供任何 URL 段,它将默认为左边红线行中指定的“Home”控制器和“Index”方法。
第一个 URL 段决定要运行的控制器类。 localhost: 44399映射到 EdisonTestController 类。
第二个 URL段决定类上的操作方法。 localhost:44399/EdisonTest/GetOwnerName 将触发 EdisonTestController 类的GetOwnerName 运行。 请注意,只需浏览到 localhost:xxxx/EdisonTest ,而GetOwnerName 方法默认调用。 原因是 GetOwnerName 是默认方法,如果未显式指定方法名称,则将在控制器上调用它。
第三个URL 段 ( id ) 针对的是路由数据。
测试:
2.2 增加参数
修改代码,将一些参数信息从 URL 传递到控制器。
l 使用 C# 可选参数功能指示,未为 numTimes 参数传递值时该参数默认为 1。
l 使用 HtmlEncoder.Default.Encode 防止恶意输入(即 JavaScript)损害应用。
l 在 $”I am Edison.Feng, you are {name}. Number of Times:{numTimes}”中使用内插字符串。
测试:
2.3 参数路由
参数也可以作为路由:
测试:
问题1:路由的第三部分怎么解析的?
问题2:路由的第三部分的问号表示什么?
2.4 增加一个View视图
目的:消除前面的硬编码,不直接返回HTML文件内容,而是返回视图对象:
l 使用 Razor 视图文件来顺利封装为客户端生成 HTML 响应。
l 使用 Razor 创建视图模板文件。 基于 Razor 的模板具有“.cshtml”文件扩展名。 它们提供了一种巧妙的方法来使用 C# 创建 HTML 输出。
l 右键单击“Views”文件夹,然后单击“添加”>“新文件夹”,并将文件夹命名为“EdisonTest”。
l 右键单击“Views/EdisonTest”文件夹,然后单击“添加”>“新项”。
l 在“添加新项 – MvcMovie”对话框中
l 在右上角的搜索框中,输入“视图”
l 选择“Razor 视图”
l 保持“名称”框的值:getownername.cshtml。
l 选择“添加”
修改视图文件getownername.cshtml:
修改默认路由,Startup.cs:
修改控制器,增加一个get方法:
测试:
2.5 给视图传点数据
使用ViewData在视图和控制器之间传递数据:
(1)修改控制器
(2)修改视图
(3)测试
3 数据库操作
3.1 将真实的数据存在数据库中,并取出来
l 结合 Entity Framework Core (EF Core) 使用这些类来处理数据库。 EF Core 是对象关系映射 (ORM) 框架,可以简化需要编写的数据访问代码。
l 要创建的模型类称为 POCO 类(源自“简单传统 CLR 对象”),因为它们与 EF Core 没有任何依赖关系。 它们只定义将存储在数据库中的数据的属性。
3.2 新增一个模型Model
选中Models文件夹,右键菜单……
3.3 增加属性
数据库需要 Id 字段以获取主键。
[DataType(DataType.Date)] :DataType 属性指定数据的类型 ( Date )。
通过此特性:
用户无需在数据字段中输入时间信息。
仅显示日期,而非时间信息。
DataAnnotations
3.4 “脚手架”工具
l 脚手架:Scaffold,或者翻译为基架
l .net core通过脚手架工具(Scaffolded Item)生成页面,用于对模型Model执行创建、读取、更新和删除 (CRUD) 操作
3.5 使用EF Core的视图
l 模型类:选择刚刚建好的模型类Movie
l 数据Context类:新建,默认命名为MvcMovie1Context
l 视图:默认
l 控制器名称:默认
3.6 “搭建基架”过程自动创建哪些文件?
l EF Core数据库Context类
l 控制器
l Razor视图文件(CRUD)
l Create
l Index
l Details
l Edit
l Delete
3.7 EF Core迁移功能
不使用EFCore迁移功能,只“搭建基架”则程序运行提示SqlException:不能打开数据库
l 初始迁移
l 进入PMC(即程序包管理控制台)
l 输入Add-Migration Initial并回车,生成用于创建初始数据库架构的代码,数据库架构基于在 MvcMovieContext 类中指定的模型。Initial 参数是迁移名称
l 输入Update-Database并回车,在 Migrations/{time-stamp}_InitialCreate.cs 文件中运行 Up 方法。Migrations/{time-stamp}_InitialCreate.cs用于创建数据库
l 依赖注入
l 脚手架工具已经把数据上下文类MvcMovie1Context注入到容器services中
l AddDbContext 指定数据库和连接字符串
l =>是Lambda运算符
l 数据上下文类为 Movie 模型协调 EF Core 功能
l (创建、读取、更新、删除等)
l 实体集DbSet对应数据库的数据表
l 通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。
l 进行本地开发时, ASP.NET Core 配置系统 在 appsettings.json 文件中读取数据库连接字符串。
3.8 CRUD: Details
l Details方法
l 将强类型模型对象传递给视图:凭借此强类型方法可更好地对代码进行编译时检查
l FirstOrDefaultAsync返回满足条件的第一个元素,或者在不满足条件下的默认元素
l m => m.Id == id 元素的ID等于给定的ID
l Details.cshtml
l @model MvcMovie1.Models.Movie
l 通过将 @model 语句包括在视图文件的顶端,
l 可以指定视图期望的对象类型
3.9 CRUD: Index
l Index方法
l ToListAsync异步创建一个List
l Index.cshtml
3.10 CRUD: Edit
3.11 CRUD: Create
3.12 CRUD: Delete
4 扩展更多的
4.1 数据库连接字符串
l DbContextOptionsBuilder.UseSqlServer
l IConfiguration.GetConnectionString
l AppSettings.json
3.2 SQL Server Express LocalDB
l SQL Server对象资源管理器
l 视图设计器
l 查看数据
4.3 数据库种子
l 数据库种子:没有任何数据时初始化数据
l 修改Main方法
l 增加SeedData类
测试:
l 删除数据库的数据之后测试,如图。
l 刷新数据库后查看数据
4.4 修改显示列表
l 修改列Title。
l 修改列数据显示格式
4.5 按标题搜索
l 给Index操作增加一个参数。
l s => s.Title.Contains() 代码是 Lambda 表达式
l Lambda 表达式在基于方法的 LINQ 查询中用作标准查询运算符方法的参数,如 Where 方法或 Contains,在对 LINQ 查询进行定义或通过调用方法(如 Where、Contains 或 OrderBy)进行修改前不会被执行。这意味着表达式的计算会延迟,直到真正循环访问其实现的值或者调用 ToListAsync 方法为止。
l Contains 方法在数据库上运行,而不是在 C# 代码中运行
l 在cshtml中绑定两个input标签。
l <form> 标记使用表单标记帮助器,提交表单时筛选器字符串会发布到电影控制器的 Index 操作。
l 增加一个POST Index操作
l 测试
l 不再出现过滤页面
l 修改index.cshtml
l 测试:能够转到过滤页面
4.6 按流派搜索
l 修改index操作方法
l System.linq命名空间,有两个静态类:Queryable和Enumerable
l IQueryable:where条件接收表达式,延迟执行
l IEnumerable:where条件接收一个谓词表达式(委托),立即执行
l SelectList是SelectListItem的集合,和<select>标签联合使用
l 修改index.cshtml
l 最上面一句改为:@model MvcMovie1.Models.GenreViewModel
l 在Title: <input……上面增加:
l <select asp-for=”MovieGenre” asp-items=”Model.Genres”>
l <option value=””>all</option>
l </select>
l 修改Title: <input……为Title: <input type=”text” asp-for=”searchString”>
l 把model.Title改为model.Movies[0].Title
l 把model.ReleaseDate改为model.Movies[0].ReleaseDate
l 把model.Genre改为model.Movies[0].Genre
l 把model.Price改为model.Movies[0].Price
l 把@foreach (var item in Model) {改为@foreach (var item in Model.Movies) {
4.7 增加新属性
l 修改Models/Movie.cs
l 修改控制器
l 更新Create方法的[Bind]属性
l 更新Edit方法的[Bind]属性
l 修改Views/Movies/Index.cshtml
l 更新 /Views/Movies/Create.cshtml
l 更新 /Views/Movies/Edit.cshtml
l 更新 SeedData 类
l 更新数据库
l 让EF Core重建数据库
l 对数据库直接修改表结构
l 使用Code First迁移(将新字段添加到模型,将新字段迁移到数据库)
l 进入PMC
l 执行Add-Migration Rating
l Add-Migration 命令会通知迁移框架使用当前 Movie DB 架构检查当前 Movie 模型,并创建必要的代码,将 DB 迁移到新模型。
l 名称“Rating”是任意的,用于对迁移文件进行命名。 为迁移文件使用有意义的名称是有帮助的。
l 执行Update-Database
l 如果删除 DB 中的所有记录,初始化方法会设定 DB 种子,并将包括 Rating 字段。
4.8 预校验
如下图,有如下几种标注:
l Required
l 必需,缺少则返回400错误
l MinimumLength
l 最小长度
l RegularExpression
l 正则表达式
l Range
l 范围
l StringLength
l 字串长度
l DataType
l 数据类型
l 需要禁用 jQuery 日期验证才能使用具有 DateTime 的 Range 特性
DRY原则是非常有用的:
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/196997.html