@page Razor 指令将文件转换为一个 MVC 操作,这意味着它可以处理请求。 @page 必须是页面上的第一个 Razor 指令。

@model 指令指定传递到 Razor 页面的模型类型。 在前面的示例中,@model 行使 PageModel 派生的类可用于 Razor 页面。 在页面上的 @Html.DisplayNameFor 和 @Html.DisplayForHTML 帮助程序中使用该模型。例如:

@Html.DisplayNameFor(model => model.Movie[0].Title)

DisplayNameFor检查Lambda表达式中引用的Title属性来确定显示名称。检查Lambda表达式(而非求值)。这意味着model,moedl.Movie或model.Movie[0]为null或为空时,不会存在任何访问冲突。 对 Lambda 表达式求值时(例如,使用 @Html.DisplayFor(modelItem => item.Title)),将求得该模型的属性值。

布局页

选择菜单链接(“RazorPagesMovie”、“Home”和“Privacy”)。 每页显示相同的菜单布局。 菜单布局在 Pages/Shared/_Layout.cshtml 文件中实现。

查找 @RenderBody() 行。 RenderBody 是显示全部页面专用视图的占位符,已包装在布局页中。 例如,选择 Privacy 链接后,Pages/Privacy.cshtml 视图在 RenderBody 方法中呈现。

ViewData 和布局

PageModel 基类包含 ViewData 字典属性,可用于将数据传递到某个视图。 可以使用键值模式将对象添加到 ViewData 字典。 在前面的示例中,Title 属性被添加到 ViewData 字典。

查询

[BindProperty(SupportsGet = true)]

public string ? SearchString { get; set; }

[BindProperty] 会绑定名称与属性相同的表单值和查询字符串。 在 HTTP GET 请求中进行绑定需要 [BindProperty(SupportsGet = true)]

例如:http请求:https://localhost:5001/Movies?searchString=Ghost。 筛选的电影将显示出来。

如果向“索引”页面添加了以下路由模板,搜索字符串则可作为 URL 段传递。 例如 https://localhost:5001/Movies/Ghost。则修改页面@page标记

@page "{searchString?}"

什么是模型绑定

控制器和 Razor Pages 处理来自 HTTP 请求的数据。 例如,路由数据可以提供一个记录键,而发布的表单域可以为模型的属性提供一个值。 编写代码以检索这些值,并将其从字符串转换为 .NET 类型不仅繁琐,而且还容易出错。 模型绑定会自动化该过程。 模型绑定系统:

  • 从各种源(如路由数据、表单域和查询字符串)中检索数据。
  • 将数据提供给方法参数和公共属性中的控制器和 Razor Pages。
  • 将字符串数据转换为 .NET 类型。
  • 更新复杂类型的属性。

示例

假设有以下操作方法:

[HttpGet("{id}")]
public ActionResult<Pet> GetById(int id, bool dogsOnly)

并且应用收到一个带有以下 URL 的请求:

https://contoso.com/api/pets/2?DogsOnly=true

在路由系统选择该操作方法之后,模型绑定执行以下步骤:

  • 查找 GetById 的第一个参数,该参数是一个名为 id 的整数。
  • 查找 HTTP 请求中的可用源,并在路由数据中查找 id =“2”。
  • 将字符串“2”转换为整数 2。
  • 查找 GetById 的下一个参数,该参数是一个名为 dogsOnly 的布尔值。
  • 查找源,并在查询字符串中查找“DogsOnly=true”。 名称匹配不区分大小写。
  • 将字符串“true”转换为布尔值 true

然后,该框架会调用 GetById 方法,为 id 参数传入 2,并为 dogsOnly 参数传入 true

目标

模型绑定尝试查找以下类型目标的值:

  • 将请求路由到的控制器操作方法的参数。
  • 请求路由到的 Razor Pages 处理程序方法的参数。
  • 控制器或 PageModel 类的公共属性(若由特性指定)。

[BindProperty] 属性

可应用于控制器或 PageModel 类的公共属性,从而使模型绑定以该属性为目标:

public class EditModel : PageModel
{[BindProperty]public Instructor? Instructor { get; set; }// ...
}

[BindProperties] 属性

可应用于控制器或 PageModel 类,以使模型绑定以该类的所有公共属性为目标:

[BindProperties]
public class CreateModel : PageModel
{public Instructor? Instructor { get; set; }// ...
}

HTTP GET 请求的模型绑定

默认情况下,不绑定 HTTP GET 请求的属性。 通常,GET 请求只需一个记录 ID 参数。 记录 ID 用于查找数据库中的项。 因此,无需绑定包含模型实例的属性。 在需要将属性绑定到 GET 请求中的数据的情况下,请将 SupportsGet 属性设置为 true

[BindProperty(Name = "ai_user", SupportsGet = true)]
public string? ApplicationInsightsCookie { get; set; }

默认情况下,模型绑定以键值对的形式从 HTTP 请求中的以下源中获取数据:

  1. 表单域
  2. 请求正文(对于具有 [ApiController] 属性的控制器。)
  3. 路由数据
  4. 查询字符串参数
  5. 上传的文件

对于每个目标参数或属性,按照之前列表中指示的顺序扫描源。 有几个例外情况:

  • 路由数据和查询字符串值仅用于 简单 类型。
  • 上传的文件仅绑定到实现 IFormFile 或 IEnumerable<IFormFile> 的目标类型。

如果默认源不正确,请使用下列属性之一来指定源:

  • [FromQuery] - 从查询字符串中获取值。
  • [FromRoute] - 从路由数据中获取值。
  • [FromForm] - 从发布的表单域中获取值。
  • [FromBody] - 从请求正文中获取值。
  • [FromHeader] - 从 HTTP 标头中获取值。

创建视图

在 Views/[ControllerName] 文件夹中创建特定于控制器的视图。 控制器之间共享的视图都将置于 Views/Shared 文件夹。 要创建一个视图,请添加新文件,并将其命名为与 .cshtml 文件扩展名相关联的控制器操作的相同名称。 要创建与Home控制器中 About 操作相对应的视图,请在 Views/Home 文件夹中创建一个 About.cshtml 文件.

视图发现

操作返回一个视图时,会发生称为“视图发现”的过程。 此过程基于视图名称确定使用哪个视图文件。

View 方法 的默认行为 (return View();) 旨在返回与其从中调用的操作方法同名的视图。 例如,控制器的 AboutActionResult 方法名称用于搜索名为 About.cshtml 的视图文件。 运行时首先在 Views/[ControllerName] 文件夹中搜索该视图。 如果在此处找不到匹配的视图,则会在 Shared 文件夹中搜索该视图。

用 return View(); 隐式返回 ViewResult 还是用 return View("<ViewName>"); 将视图名称显式传递给 View 方法并不重要。 在这两种情况下,视图发现都会按以下顺序搜索匹配的视图文件:

  1. Views/\[ControllerName]/\[ViewName].cshtml
  2. Views/Shared/\[ViewName].cshtml

可以提供视图文件路径而不提供视图名称。 如果使用从应用根目录开始的绝对路径(可选择以“/”或“~/”开头),则须指定 .cshtml 扩展名:

C#复制

return View("Views/Home/About.cshtml");

也可使用相对路径在不同目录中指定视图,而无需指定 .cshtml 扩展名。 在 HomeController 内,可以使用相对路径返回 Manage 视图的 Index 视图:

C#复制

return View("../Manage/Index");

同样,可以用“./”前缀来指示当前的控制器特定目录:

C#复制

return View("./About");

将数据传递给视图

使用多种方法将数据传递给视图:

  • 强类型数据:viewmodel
  • 弱类型数据
    • ViewData (ViewDataAttribute)
    • ViewBag

强类型数据 (viewmodel)

最可靠的方法是在视图中指定模型类型。 此模型通常称为 viewmodel。 将 viewmodel 类型的实例传递给此操作的视图。

使用 viewmodel 将数据传递给视图可让视图充分利用强类型检查。 强类型化(或强类型)意味着每个变量和常量都有明确定义的类型(例如 stringint 或 DateTime)。 在编译时检查视图中使用的类型是否有效。

没有针对可以提供给视图的模型类型的限制。 建议使用普通旧 CLR 对象 (POCO) viewmodel,它几乎没有已定义的行为(方法)。 通常,viewmodel 类要么存储在 Models 文件夹中,要么存储在应用根目录处的单独 ViewModels 文件夹中。

弱类型数据(ViewData[ViewData] 属性和 ViewBag

ViewBag默认情况下不可用以用于 Razor PagesPageModel类。

除了强类型视图,视图还可以访问弱类型(也称为松散类型)的数据集合。 与强类型不同,弱类型(或松散类型)意味着不显式声明要使用的数据类型。 可以使用弱类型数据集合将少量数据传入及传出控制器和视图。

传递数据于... 示例
控制器和视图 用数据填充下拉列表。
视图和布局视图 从视图文件设置布局视图中的 <title> 元素内容。
分部视图和视图 基于用户请求的网页显示数据的小组件。

可以通过控制器和视图上的 ViewData 或 ViewBag 属性来引用此集合。 ViewData 属性是弱类型对象的字典。 ViewBag 属性是 ViewData 的包装器,为基础 ViewData 集合提供动态属性。 注意:对于 ViewData 和 ViewBag,键查找都不区分大小写。

ViewData 和 ViewBag 在运行时进行动态解析。 由于它们不提供编译时类型检查,因此使用这两者通常比使用 viewmodel 更容易出错。 出于上述原因,一些开发者希望尽量减少或根本不使用 ViewData 和 ViewBag

ViewData

ViewData 是通过 string 键访问的 ViewDataDictionary 对象。 字符串数据可以直接存储和使用,而不需要强制转换,但是在提取其他 ViewData 对象值时必须将其强制转换为特定类型。 可用于 ViewData 将数据从控制器传递到视图和视图中,包括 部分视图 和 布局。

以下是在操作中使用 ViewData 设置问候语和地址值的示例:

public IActionResult SomeAction()
{ViewData["Greeting"] = "Hello";ViewData["Address"]  = new Address(){Name = "Steve",Street = "123 Main St",City = "Hudson",State = "OH",PostalCode = "44236"};return View();
}

在视图中处理数据:

@{// Since Address isn't a string, it requires a cast.var address = ViewData["Address"] as Address;
}@ViewData["Greeting"] World!<address>@address.Name<br>@address.Street<br>@address.City, @address.State @address.PostalCode
</address>

[ViewData] 特性

使用 ViewDataDictionary 的另一种方法是 ViewDataAttribute。 控制器或 Razor 页面模型上使用 [ViewData] 特定的属性将其值存储在字典中并从中进行加载。

在下面的示例中,“Home”控制器包含使用 [ViewData] 标记的 Title 属性。 About 方法设置“关于”视图的标题:

public class HomeController : Controller
{[ViewData]public string Title { get; set; }public IActionResult About(){Title = "About Us";ViewData["Message"] = "Your application description page.";return View();}
}

在布局中,从 ViewData 字典读取标题:

<!DOCTYPE html>
<html lang="en">
<head><title>@ViewData["Title"] - WebApplication</title>...

ViewBag

ViewBag默认情况下不可用以用于 Razor PagesPageModel类。

ViewBag 是 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData 对象,可提供对存储在 ViewData 中对象的动态访问权限。 ViewBag 不需要强制转换,因此使用起来更加方便。 下例演示如何使用与上述 ViewData 有相同结果的 ViewBag

public IActionResult SomeAction()
{ViewBag.Greeting = "Hello";ViewBag.Address  = new Address(){Name = "Steve",Street = "123 Main St",City = "Hudson",State = "OH",PostalCode = "44236"};return View();
}

CSHTML复制

@ViewBag.Greeting World!<address>@ViewBag.Address.Name<br>@ViewBag.Address.Street<br>@ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>

ViewData 和 ViewBag 之间差异的摘要

ViewBag默认情况下不可用以用于 Razor PagesPageModel类。

  • ViewData

    • 派生自 ViewDataDictionary,因此它有可用的字典属性,如 ContainsKeyAddRemove 和 Clear
    • 字典中的键是字符串,因此允许有空格。 示例: ViewData["Some Key With Whitespace"]
    • 任何非 string 类型均须在视图中进行强制转换才能使用 ViewData
  • ViewBag
    • 派生自 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData,因此它可使用点表示法 (@ViewBag.SomeKey = <value or object>) 创建动态属性,且无需强制转换。 ViewBag 的语法使添加到控制器和视图的速度更快。
    • 更易于检查 NULL 值。 示例: @ViewBag.Person?.Name

ASP .NET core UI笔记相关推荐

  1. Asp.net core 学习笔记 ( Web Api )

    更新 : 2019-06-03  web api 返回 json 的情况下默认会把属性 PascalCase 变成 camelCase 很贴心哦. 如果你不喜欢可以修改它 services.AddMv ...

  2. Asp.net core 学习笔记 ( ef core )

    更新: 2019-06-12 不小心踩坑 var adidas = new Supplier { name = "adidas" }; Db.Suppliers.Add(adida ...

  3. asp.net core学习笔记

    控制器Controller l 命名以Controller结尾 public class TestController : Controller{ public IActionResult SayHe ...

  4. Asp.Net Core部署:早知道,还是docker!以及一点碎碎念

    前言 AspNetCore技术栈在我们团队里的使用也有一段时间了,之前的部署方式一直是本地编译之后上传可执行文件到服务器,使用supervisor来管理进程这种很原始的方式. 参考之前的文章:Asp. ...

  5. ASP.NET Core 3.x 学习笔记(7)——Blazor

    ASP.NET Core 3.x 学习笔记(7)--Blazor ASP.NET Core 3.x 学习笔记(7)--Blazor 编程模式对比 Blazor 客户端宿主模型 Mono 服务器端宿主模 ...

  6. 小范笔记:ASP.NET Core API 基础知识与Axios前端提交数据

    跟同事合作前后端分离项目,自己对 WebApi 的很多知识不够全,虽说不必要学全栈,可是也要了解基础知识,才能合理设计接口.API,方便与前端交接. 晚上回到宿舍后,对 WebApi 的知识查漏补缺, ...

  7. ASP.NET Core 2 学习笔记(七)路由

    ASP.NET Core通过路由(Routing)设定,将定义的URL规则找到相对应行为:当使用者Request的URL满足特定规则条件时,则自动对应到相符合的行为处理.从ASP.NET就已经存在的架 ...

  8. ASP.NET Core 2 学习笔记(四)依赖注入

    原文:ASP.NET Core 2 学习笔记(四)依赖注入 ASP.NET Core使用了大量的依赖注入(Dependency Injection, DI),把控制反转(Inversion Of Co ...

  9. 《ASP.NET Core In Action》读书笔记系列五 ASP.NET Core 解决方案结构解析1

    <ASP.NET Core In Action>读书笔记系列五 ASP.NET Core 解决方案结构解析1 参考文章: (1)<ASP.NET Core In Action> ...

最新文章

  1. 爬虫之selenium替换user-agent
  2. tensorflow.python.framework.errors_impl.DataLossError:
  3. windows10上为jupyter notebook切换指定conda环境
  4. OpenCV官方文档 理解k - means聚类
  5. .NET Core SignalR Redis底板详解(前言)
  6. 这是我在网上安的第一个窝!
  7. 数组面试题--数组求和
  8. [转载] python中字典中追加_python 中字典中的删除,pop 方法与 popitem 方法
  9. 旋转倒立摆资料【包含源码和教程】!!
  10. PhotoShop cc 2017安装 zeplin插件
  11. 前端实现PDF预览打印
  12. 第八讲:1602液晶(郭天祥)
  13. boost::geometry::ever_circling_iterator用法的测试程序
  14. 阿里面试官Redis把我问到哑口无言…
  15. 基于单片机的温度计设计
  16. cv2.erode函数
  17. 好用又免费的办公软件
  18. echarts y轴只显示5个刻度_Echarts 双Y轴刻度不一致
  19. 计算机应用专业有没有校企合作,高职计算机应用专业校企合作的思考
  20. 反光柱建图和定位总结

热门文章

  1. 极度未知HyperX夺宝日—HyperX Cloud Alpha S加强版游戏耳机来了
  2. 年记2020,新年快乐
  3. 领导离职,我是否应该跟领导一起走
  4. 集成环境注意事项小结
  5. mybatis-plus自动填充插入时间后有8小时时差
  6. 发明计算机作文300字,我发明的机器人作文300字
  7. android手机两年变卡,安卓手机为什么用到两到三年以后就会开始变卡?
  8. 数据结构:线性结构和非线性结构的理解
  9. antd-mobile-InputItem ios下键盘换行修改前往
  10. 全国A级景点信息与分布数据