作者:陈广 日期:2018-3-2
Razor是ASP.NET Core 2.0版本的一个新功能,它使得我们可以在HTML中嵌入C#代码,实现复杂逻辑。感觉跟现在最流行的Vue有点类似,不过我更喜欢Razor,C#代码看着更亲切。当然Vue是纯客户端编程,由浏览器的JavaScript实现,而Razor属于服务端编程,两者根本不是一回事。本文从空白开始,一步步创建Razor页面,让大家有个大致了解,看完本文再去看ASP.NET Core 2.0文档的Razor相关部分,会更容易理解。有关Razor的文档,我已经翻译了不少。
这次创建Razor页面,我们还是使用空白项目,这样更方便理解它的流程。创建过程和之前写的HTTP初探类似。在本地硬盘新建一个razor 文件夹,鼠标右击此文件夹,弹出菜单选择Open with Code,从而使用vscode打开此文件夹。打开终端输入如下命令创建一个空白项目:
dotnet new empty
MVC中间件默认就是使用的Razor,所以只需加入MVC中间件,就可以使用Razor了。
打开Startup.cs 文件,更改Startup
类代码如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
在Razor文件夹下新建一个Pages文件夹,然后在Pages文件夹下面新建一个Index.cshtml文件。完成后文件结构如下图所示:
默认情况下,.NET Core会去Pages文件夹查找
.cshtml
文件,所以文件必须位于根目录下,并且名称必须为Pages。当然,这些是可以更改的。
在Index.cshtml文件中输入如下代码:
@page
<h1>这是Razor页面</h1>
按F5运行程序,效果如下图所示:
相比上次我们讲HTTP写和程序,这次没有controller,没有路由,直接就可以打开网页了。关键之处就在
@page
指令。@page
使文件转换为一个MVC action,这意味着它将直接处理请求,而无需通过controller
处理。@page
必须是页面上的第一个Razor指令。
现在我们加入C#代码,领略一下Razor的强大,将Index.cshtml代码更改如下:
@page
<p>当前时间为:@DateTime.Now</p>
运行效果如下图所示:
在HTML中使用C#代码非常简单,只需一个
@
,然后后面写C#代码就可以了。当然,会有很多限制,请参考微软文档Razor语法。
现在更改需求,把程序写得更复杂一些,加入打招呼功能,不同时间招呼用语不同:
Index.cshtml更改代码如下:
@page
@{
var hour = DateTime.Now.Hour;
var message = "";
if (hour > 0 && hour <= 5)
{
message = "夜深了,快睡觉吧!";
}
else if (hour > 5 && hour <= 11)
{
message = "早上好!";
}
else if (hour > 11 && hour <= 14)
{
message = "中午好!";
}
else if (hour > 15 && hour <= 18)
{
message = "下午好!";
}
else if (hour > 18 && hour <= 24)
{
message = "晚上好!";
}
}
<p>@message 当前时间为:@DateTime.Now</p>
运行效果如下:
可以看到,大段代码块可以放在
@{}
内。当然,你也可以使用另一种形式实现上述功能。
@page
@{
var hour = DateTime.Now.Hour;
var timeTxt = $"当前时间为:{DateTime.Now}";
}
@if (hour > 0 && hour <= 5)
{
<p>夜深了,快睡觉吧! @timeTxt</p>;
}
else if (hour > 5 && hour <= 11)
{
<p>早上好! @timeTxt</p>;
}
else if (hour > 11 && hour <= 14)
{
<p>中午好! @timeTxt</p>;
}
else if (hour > 15 && hour <= 18)
{
<p>下午好! @timeTxt</p>;
}
else if (hour > 18 && hour <= 24)
{
<p>晚上好! @timeTxt</p>;
}
运行效果和之前的一样。从上述代码可知,if
语句即可放在代码块中,也可和HTML混合在一起使用。而且各类判断、循环语句皆可这样使用。以程序员的思维去写HTML,这功能实在是太强大了,我喜欢!
如果页面逻辑比较复杂,C#代码很多,你也可以使用 .cshtml.cs
扩展名文件将后台代码分开。若要使 .cshtml
和 .cshtml.cs
自动关联,需要遵守以下约定:
.cshtml
和 .cshtml.cs
文件的文件名相同,不同的只是扩展名.cshtml.cs
文件中的类继承自PageModel
,并命名为<文件名>Model
,此例的文件名为Index
,所以类名应为IndexModel
。.cshtml
文件需要使用@using
指令引入code-behind文件所在命名空间。.cshtml
文件需要使用@model
指令指定传递到视图的model类型。.cshtml
文件需要使用Model
访问传递到视图的model,具体到本例就是IndexModel
。接下来在Pages文件夹下创建Index.cshtml.cs文件,并输入如下代码:
using System;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace razor.Pages
{
public class IndexModel : PageModel
{
public string Message
{
get
{
var hour = DateTime.Now.Hour;
if (hour > 0 && hour <= 5)
{
return "夜深了,快睡觉吧!";
}
else if (hour > 5 && hour <= 11)
{
return "早上好!";
}
else if (hour > 11 && hour <= 14)
{
return "中午好!";
}
else if (hour > 15 && hour <= 18)
{
return "下午好!";
}
else
{
return "晚上好!";
}
}
}
}
}
注意:namespace razor.Pages
代码指定了IndexModel
类的命令空间,需要根据实际情况编写,由于本例项目名为razor
,所以命名空间为razor.Pages
。如果你建的项目名称(项目所在文件夹名称)不一样,请按实际情况进行更改。
这里我们把之前的Message
包装成了IndexModel
的一个属性。
更改Index.cshtml
文件代码如下:
@page
@using razor.Pages
@model IndexModel
<p>@Model.Message 当前时间为:@DateTime.Now</p>
运行程序,可以看到运行结果和之前的例子一样,但这一次,我们把逻辑放在了code-behind文件内,跟页面进行了分离。
当Pages文件夹中有多个视图使用相同的Razor指令来执行操作时,例如导入命名空间或执行依赖注入。可在一个共同的_ViewImports.cshtml
文件中指定由许多视图共享的指令。
在Pages文件夹中新建一个_ViewImports.cshtml
文件,加入如下代码:
@using razor.Pages
并将Index.cshtml
文件中的同一条语句删除,变为如下:
@page
@model IndexModel
<p>@Model.Message 当前时间为:@DateTime.Now</p>
运行程序,效果相同,只是这次引入命名空间这工作由_ViewImports.cshtml
文件完成了。