RazorPage是一种基于页面的编码方式,属于ASP.NET Core MVC的一个轻量级的分支。它非常适合页面信息流等之类的需求。注意,RazorPage要求使用.NET Core 2.1 SDK 或更高版本。
构建第一个RazorPage应用
可以通过以下CLI命令来构建官方定义的模板应用。
dotnet new webapp -o RazorPagesMovie
cd RazorPagesMovie
dotnet run
支持Razor标记语法
隐式 Razor 表达式以 @
开头,后跟 C# 代码。
<p>@DateTime.Now</p>
<p>@DateTime.IsLeapYear(2016)</p>
隐式表达式不能包含空格,但C# await
关键字除外。
<p>
@await DoSomething("hello", "world")
</p>
隐式表达式不能包含C#
泛型,因为括号(<>)
内的字符会被解释为 HTML 标记。
显式 Razor 表达式由@
符号和平衡圆括号组成。
<p>
Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))
</p>
显式表达式可用于从.cshtml
文件中的泛型方法呈现输出。
<p>
@(GenericMethod<int>())
</p>
表达式编码:计算结果为字符串的 C# 表达式采用 HTML 编码。 计算结果为IHtmlContent
的 C# 表达式直接通过IHtmlContent.WriteTo
呈现。 计算结果不为IHtmlContent
的 C# 表达式通过 ToString
转换为字符串,并在呈现前进行编码。
@("<span>Hello World</span>")
该 HTML 在浏览器中显示为:
<span>Hello World</span>
HtmlHelper.Raw
输出不进行编码,但呈现为HTML标记。
Razor 代码块以 @
开头,并括在{}
中。 代码块内的 C# 代码不会呈现,这点与表达式不同。 一个视图中的代码块和表达式共享相同的作用域并按顺序进行定义。
若要定义应呈现 HTML的代码块子节,请使用 Razor<text>
标记将要呈现的字符括起来:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<text>Name: @person.Name</text>
}
若要在代码块内以HTML的形式呈现整个行的其余内容,请使用 @:
语法:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
@:Name: @person.Name
}
内置路由
默认根据Pages
文件夹里的页面名称自动适配。比如About.cshtml
对应的路由为/About
,支持参数查询。
<a asp-page="./About" asp-route-id="@item.ID">Details</a>
上述代码会在 Razor 文件中参与创建和呈现 HTML
元素。包括 Razor 页面(路由是相对的)、asp-page
和路由 ID (asp-route-id)
动态生成HTML href
特性值。
数据访问
通过依赖关系注入进行生成,EF Core数据库上下文在应用程序启动期间通过依赖关系注入进行注册,RazorPage通过构造函数提供相应服务。
先在ConfigureServices
中注入数据上下文。
services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
然后在Page构造函数中获取数据上下文进行数据访问操作。
public AboutModel(SchoolContext context)
{
_context = context;
}
编程模式
默认是异步编程,可以更有效地利用服务器资源。也支持使用同步编程。
在 EF Core 中只会异步执行导致查询或命令被发送到数据库的语句。 这包括 ToListAsync
、SingleOrDefaultAsync
、FirstOrDefaultAsync
和 SaveChangesAsync
。 不包括只会更改 IQueryable
的语句,例如:
var students = context.Students.Where(s => s.LastName == "Davolio")
EF Core 上下文并非线程安全,请勿尝试并行执行多个操作。
钩子函数
OnGet
/ OnGetAsync
:初始化页面所需的任何状态。
OnPost
/ OnPostAsync
:表单提交处理方法。
除了默认的钩子函数,还可以通过asp-page-handler
指定自定名称的钩子函数。
<form method="POST">
<div>Username: <input asp-for="username" /></div>
<input type="submit" value="Search" asp-page-handler="Search" class="btn btn-primary btn-xs" />
</form>
上述表单将通过.cshtml.cs
文件代码中OnPostSearch()
/OnPostSearchAsync()
钩子函数来处理。
参数处理
将参数传递给处理方法有两种方法:表单输入、表单元素借助 asp-route Tag Helper
。
对于表单输入作为输入参数,名称必须是同步的。表单元素的名称必须与处理方法参数的名称相匹配。
<form method="POST">
<input type="text" name="query"/>
<button type="submit" asp-page-handler="Search">Search</button>
</form>
对应的处理方法如下:
public async Task OnPostSearchAsync(string query)
{
//do somethings
}
第二种是通过路由发送参数。
<form method="POST" asp-page-handler="Delete" asp-route-id="id">
<button>Delete</button>
</form>