这里介绍了Razor基本用法

  1. 创建带PageModel的Razor 页面
  2. 使用数据库
  3. 展示数据
  4. 更新数据
  5. 筛选器

准备工作

  1. 初始化空的项目(终端输入:dotnet new web -n=Razor)
  2. Nuget添加Microsoft.EntityFrameworkCore.SqlServer 和 Microsoft.EntityFrameworkCore.Design 
  3. 添加必要服务

   ConfigureServices添加Razor支持

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}

  修改app.UseEndpoints为

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});

添加数据库

 1. 添加模型
[Table("Book")]
public class Book
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; } [Display(Name = "书名")]
[Required(ErrorMessage = "书名不能为空")]
[StringLength(, ErrorMessage = "书名最大长度为50")]
public string Name { get; set; } [Display(Name = "单价")]
[Column(TypeName = "decimal(18, 2)")]
[Range(0.01, , ErrorMessage = "单价范围只能在(0.01 ~ 10000)"), DataType(DataType.Currency)]
public decimal UnitPrice { get; set; } [Display(Name = "出版日期")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime PublicationDate { get; set; } [Display(Name = "创建时间")]
[DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")]
public DateTime CreateTime { get; set; } [Display(Name = "最后更新时间")]
[DataType(DataType.DateTime), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")]
public DateTime? LastUpdateTime { get; set; }
}

2. 添加DbContext

public class RazorDbContext : DbContext
{
public RazorDbContext(DbContextOptions<RazorDbContext> options)
: base(options)
{ } public DbSet<Razor.Models.Book> Book { get; set; }
}

3. 安装dotnet-ef(全局安装),终端输入

dotnet tool install --global dotnet-ef
4. 添加迁移
dotnet ef migrations add InitialDb

5. 更新到数据库

dotnet ef database update InitialDb

6. 添加种子数据

public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
var options = serviceProvider.GetRequiredService<DbContextOptions<RazorDbContext>>();
using (var context = new RazorDbContext(options))
{
if (context.Book.Any())
{
return;
} context.Book.AddRange(
new Models.Book
{
Name = "算法之美",
UnitPrice = 26.99m,
PublicationDate = DateTime.Parse("2016-08-20"),
CreateTime = DateTime.Now
},
new Models.Book
{
Name = "大话设计模式",
UnitPrice = 28.03m,
PublicationDate = DateTime.Parse("2015-06-12"),
CreateTime = DateTime.Now
},
new Models.Book
{
Name = "幸福的陷阱",
UnitPrice = 30.59m,
PublicationDate = DateTime.Parse("2018-09-13"),
CreateTime = DateTime.Now
},
new Models.Book
{
Name = "墨菲定律",
UnitPrice = 32.12m,
PublicationDate = DateTime.Parse("2018-09-13"),
CreateTime = DateTime.Now
}
); context.SaveChanges();
}
}
}

经过上面的步骤就可以在程序中使用数据库

Razor页面

一、路由
@page指令
  1. 必须是页面上的第一个 Razor 指令
  2. 默认情况,Url根据文件夹层次结构生成,也可以在@page 后面指定路由
  3. 可以对参数约束,例如:{id:int}

二、读取数据(以上面模型为例)

  1. 创建Index页面

dotnet new page -o=Pages -na="Razor.Pages" -n="Index"

  2. PageModel 的OnGet读取数据

public class IndexModel : PageModel
{
private readonly Data.RazorDbContext _dbContext;
public IndexModel(Data.RazorDbContext dbContext)
{
_dbContext = dbContext;
} public List<Models.Book> Books { get; set; } public IActionResult OnGet()
{
if (_dbContext == null)
{
return NotFound();
} Books = _dbContext.Book
.AsNoTracking()
.ToList();
return Page();
}
}

  3. 页面展示数据

@page
@model IndexModel
@{
ViewData["Title"] = "图书管理";
}
<table class="table table-bordered text-center">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Books[].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Books[].UnitPrice)
</th>
<th>
@Html.DisplayNameFor(model => model.Books[].PublicationDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Books[].CreateTime)
</th>
<th >
@Html.DisplayNameFor(model => model.Books[].LastUpdateTime)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Books)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.UnitPrice)
</td>
<td>
@Html.DisplayFor(modelItem => item.PublicationDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.CreateTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastUpdateTime)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Id">编辑</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">删除</a>
</td>
</tr>
}
</tbody>
</table>

三、更新数据

  1. 创建Edit页面

dotnet new page -o=Pages -na="Razor.Pages" -n="Edit"

  2. PageModel拉去数据

public IActionResult OnGet(int? id)
{
if (id == null)
{
return NotFound();
} Book = _dbContext.Book
.AsNoTracking()
.FirstOrDefault(m => m.Id == id); if(Book == null)
{
return NotFound();
} return Page();
}

  3. 编辑Edit页面

@page "{id:int}"
@model Razor.Pages.EditModel
@{
ViewData["Title"] = "编辑书本";
}
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Book.Id" />
<div class="form-group">
<label asp-for="Book.Name" class="control-label"></label>
<input asp-for="Book.Name" class="form-control" />
<span asp-validation-for="Book.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Book.UnitPrice" class="control-label"></label>
<input asp-for="Book.UnitPrice" class="form-control" />
<span asp-validation-for="Book.UnitPrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Book.PublicationDate" class="control-label"></label>
<input asp-for="Book.PublicationDate" class="form-control" />
<span asp-validation-for="Book.PublicationDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="保存" class="btn btn-primary" />
</div>
</form>
</div>
</div>

  4. OnPost处理请求

public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
} var model = _dbContext.Book.FirstOrDefault(m => m.Id == Book.Id); if (model == null)
{
return NotFound();
} model.Name = Book.Name;
model.PublicationDate = Book.PublicationDate;
model.UnitPrice = Book.UnitPrice; _dbContext.SaveChanges(); return RedirectToPage("Index");
}

用asp-for生成的输入框,会加上客户端验证,查看原代码可以发现

<input class="form-control" type="text" data-val="true" data-val-length="书名最大长度为50" data-val-length-max="50" data-val-required="书名不能为空" id="Book_Name" maxlength="50" name="Book.Name" value="大话设计模式" />

它是根据模型定义的验证,生成属性,然后用jquery-validation验证,这样我们没有写一行前端代码就能达到客户端验证效果,微软真的把DRY做到极致。当然后端的验证也是不能漏的

筛选器

Razor 页面筛选器提供的以下方法可在全局或页面级应用:

同步方法:

  • OnPageHandlerSelected:在选择处理程序方法后但在模型绑定发生前调用。
  • OnPageHandlerExecuting:在执行处理器方法前,模型绑定完成后调用。
  • OnPageHandlerExecuted:在执行处理器方法后,生成操作结果前调用。

异步方法:

  • OnPageHandlerSelectionAsync:在选择处理程序方法后,但在模型绑定发生前,进行异步调用。
  • OnPageHandlerExecutionAsync:在调用处理程序方法前,但在模型绑定结束后,进行异步调用。
一、全局筛选器
  1. 创建GlobalPageFilter类,实现IPageFilter接口
public class GlobalPageFilter : IPageFilter
{
private readonly ILogger _logger; public GlobalPageFilter(ILogger logger)
{
_logger = logger;
} public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
{
_logger.LogDebug("Global Filter OnPageHandlerSelected called.");
} public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
{
_logger.LogDebug("Global Filter OnPageHandlerExecuting called.");
} public void OnPageHandlerSelected(PageHandlerSelectedContext context)
{
_logger.LogDebug("Global Filter OnPageHandlerSelected called.");
}
}

  2. 创建过滤器工厂类,实现IFilterFactory接口

public class GlobalPagerFilterWithFactory : IFilterFactory
{
public bool IsReusable => false; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
var logger = serviceProvider.GetService<ILogger<Filters.GlobalPageFilter>>(); return new Filters.GlobalPageFilter(logger);
}
}

  3. ConfigureServices添加RazorPage选项

services.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.ConfigureFilter(new Factories.GlobalPagerFilterWithFactory());
});

二、特定PageModel筛选器

  在PageModel里面重载
public override void OnPageHandlerSelected(Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext context)
{
_logger.LogDebug("OnPageHandlerSelected");
}
//在执行处理器方法前,模型绑定完成后调用
public override void OnPageHandlerExecuting(Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext context)
{
_logger.LogDebug("OnPageHandlerExecuting");
}
//在执行处理器方法后,生成操作结果前调用
public override void OnPageHandlerExecuted(Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext context)
{
_logger.LogDebug("OnPageHandlerExecuted");
}

示例代码:https://github.com/WilsonPan/AspNetCoreExamples/tree/master/Razor

【ASP.NET Core学习】Razor页面的更多相关文章

  1. ASP.NET Core使用Razor页面

    ASP.NET Core使用Razor页面 Razor是ASP.NET的页面引擎,在ASP.NET MVC 3以后被广泛使用,我在之前的博客中有所介绍,需要更多了解的朋友请移步[Razor语法] 在A ...

  2. 独立使用Asp.net Core 的razor模板 (一):Razor引擎的一些细节

    由于最近需要写一些界面稍微好看点的Winform程序,如果用原生控件,,想要达到好看的程度,需要花费比较大的功夫,因为之前使用过CefSharp,因此发觉如果是使用CEF+Html的方式,界面可以相对 ...

  3. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  4. Asp.Net Core学习笔记:入门篇

    Asp.Net Core 学习 基于.Net Core 2.2版本的学习笔记. 常识 像Django那样自动检查代码更新,自动重载服务器(太方便了) dotnet watch run 托管设置 设置项 ...

  5. ASP.NET Core学习系列

    .NET Core ASP.NET Core ASP.NET Core学习之一 入门简介 ASP.NET Core学习之二 菜鸟踩坑 ASP.NET Core学习之三 NLog日志 ASP.NET C ...

  6. ASP.NET Core学习指导

    ASP.NET Core 学习指导 "工欲善其事必先利其器".我们在做事情之前,总应该做好充分的准备,熟悉自己的工具.就像玩游戏有一些最低配置一样,学习一个新的框架,也需要有一些基 ...

  7. Asp.Net Core 学习教程2、使用ASP.NET Core中的RazorPages

    1.创建一个Asp.Net Core Web应用程序 1.1.打开VS2019 新建项目 1.2.选好项目位置后进入线面界面,选择Web应用程序 1.3.进去的页面结构如下 Pages 文件夹:包含 ...

  8. ASP.NET Core 学习笔记 第一篇 ASP.NET Core初探

    前言 因为工作原因博客断断续续更新,其实在很早以前就有想法做一套关于ASP.NET CORE整体学习度路线,整体来说国内的环境的.NET生态环境还是相对比较严峻的,但是干一行爱一行,还是希望更多人加入 ...

  9. ASP.NET Core学习零散记录

    赶着潮流听着歌,学着.net玩着Core 竹子学Core,目前主要看老A(http://www.cnblogs.com/artech/)和tom大叔的博客(http://www.cnblogs.com ...

随机推荐

  1. HNU_小初高数学学习软件_功能说明

    结对编程项目主要功能: 1.用户注册功能.用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册: 2.用户完成注册后,界面提示设置密码,用户输入两次密码匹配后设置密码成功.密码6-1 ...

  2. 性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿

    列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表 思路 列表中固定只显示少量的数据,比如60条 在列表滚动的时 ...

  3. mysql root用户登录后无法查看数据库全部表

    可能是把root@localhost用户删掉了. 首先停掉mysql服务,在/etc/my.cnf中添加 skip-grant-tables,同时可以添加skip-networking选项来禁用网络功 ...

  4. 虚拟现实中自由步行(free-space walking)

    之前我们讲到了虚拟现实中漫游方式的分类.虚拟现实中的漫游(travel/navigate)方式,即是应用提供给用户的,在虚拟环境中移动的方式.虚拟现实的漫游方式中,有一种被称为“完全动作线索”1,即用 ...

  5. 02·nginx进阶·服务优化配置管理

    企业场景常用的Nginx http功能模块汇总 ngx_ http_ core_ module 包括-些核心的http 参数配置,对应Nginx的配置为HTTP区块部分 ngx_ http _acce ...

  6. [Android Studio] 2019年Android Studio配置指北

    Android Studio是我学习Android开发路上的第一块绊脚石,新建一个项目,一行代码没动,直接编译不起来,我太难了,所以本文叫指北 本文讲解在9102年如何在国内网络不通畅的情况下流畅的使 ...

  7. Docker下配置nacos

    前言 近段时间在学dubbo,dubbo-admin死活装不上,无论是本地还是docker,所以把目光投向了其他配置中心,我选定的是阿里新开源的nacos. 正文 拉取镜像到本地docker dock ...

  8. 如何在 Linux 和 windows 启动使用 Dubbo 和 ZK

    今天的知识点有 3 个: Linux 下安装.配置 JDK. Windows 下启启动 dubbo 和 zookeeper. Linux 下启动 dubbo 和 zookeeper. 1.Linux ...

  9. ASP.NET Web API 2系列(三):查看WebAPI接口的详细说明及测试接口

    引言 前边两篇博客介绍了Web API的基本框架以及路由配置,这篇博客主要解决在前后端分离项目中,为前端人员提供详细接口说明的问题,主要是通过修改WebApi HelpPage相关代码和添加WebAp ...

  10. Chrome 和 Chromedriver 的安装和配置

    1.Chrome 下载安装地址:https://www.google.com/intl/zh-CN_ALL/chrome/ 2.Chromedriver的安装 方法一: (1) brew cask i ...