问题

如何在ASP.NET Core 2.0中使用Razor引擎来创建视图?

答案

新建一个空项目,修改Startup.cs,添加MVC服务和请求中间件:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}  

添加Controllers目录,并添加HomeController控制器:

public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}

添加Views/Home目录,并添加Razor视图Index.cshtml:

@{
var birthDate = new DateTime(1930, 8, 26);
} <strong>Hello MVC Razor</strong> <p>James Bond, you were born @birthDate.ToString("yyyy-MM-dd")</p> <p>James Bond is about @((DateTime.Now - birthDate).Days / 365) years old</p> <p>@("<strong>Hello World</strong>")</p> <p>@Html.Raw("<strong>james@bond.com</strong>")</p> @{
var isHungry = true;
var gender = 0;
IEnumerable<string> friends = new[] { "Thor", "Hulk", "Iron Man" };
var technology = "asp.net mvc";
var count = technology.Count();
} <p>
@if (isHungry)
{
<text>I'm hungry</text>
}
else
{
<text>I'm full</text>
}
</p> @switch (gender)
{
case 0:
<p>Male</p>
break;
case 1:
<p>Female</p>
break;
default:
break;
} @for (int i = 0; i < technology.Length; i++)
{
@technology[i].ToString().ToUpper()
} <ul>
@foreach (var item in friends)
{
<li>@item</li>
}
</ul> @try
{
var a = 1; var b = 0;
var result = a / b; // divide by zero
}
catch (Exception ex)
{
<p>@ex.Message</p>
}

此时的目录结构如下所示:

运行,此时页面显示:

讨论

当控制器返回ViewResult时,ASP.NET Core中间件会查找并执行Razor模板(.cshtml文件)。Razor模板使用C#和HTML的混合语法来生成最终的HTML页面。

查找视图

当ViewResult执行时,它会按照如下顺序查找视图所在路径:

1. Views/[Controller]/[Action].cshtml

2. Views/Shared/[Action].cshtml

如果模板文件名和控制器方法的名称不一致,可以在ViewResult中通过参数来指定视图模板的名称:

public IActionResult AboutMe()
{
return View("Bio");
} 

Razor语法

HTML标签会原封不动的渲染到最终的HTML页面中:

<strong>Hello MVC Razor</strong>  

通过@符号从HTML过渡到C#代码。C#代码块可以用如下结构包含起来:

@{
var birthDate = new DateTime(1930, 8, 26);
}  

C#表达式可以直接通过@符号来输出到最终HTML页面:

<p>James Bond, you were born @birthDate.ToString("yyyy-MM-dd")</p>

或者用@( //C#表达式 )来包含起来:

<p>James Bond is about @((DateTime.Now - birthDate).Days / 365) years old</p>

Razor默认会对C#表达式进行HTML编码,观察下面的Razor代码以及生成到页面上的HTML结构:

<p>@("<strong>Hello World</strong>")</p>
<p>&lt;strong&gt;Hello World&lt;/strong&gt;</p>

@Html.Raw可以避免C#表达式被HTML编码,如下所示:

<p>@Html.Raw("<strong>james@bond.com</strong>")</p>
<p><strong>james@bond.com</strong></p>

    

控制结构

Razor视图中,我们可以在C#代码块中使用各种控制结构,比如@if, @switch, @for, @foreach, @while, @do while和@try。具体示例可以查看Views/Home/Index.cshtml代码。

指令

Razor视图会被转化为继承自RazorPage的C#类(内部实现,对用户透明)。而指令可以改变这些类或者视图引擎的行为。常用的指令有:

@using

向生成的C#类添加一个using指令。类似于普通的C#类,这个指令用来导入命名空间。

@model

指定传入RazorPage的泛型类型T。当控制器返回ViewResult时,可以通过参数来指定模型类型。然后在视图页面中通过Model属性来获取模型实例。

@inject

用来向视图注入服务(首先需要在Startup中在服务容器中注册此服务)。你需要提供服务类型和名称(视图中通过此名称访问服务)。视图的依赖注入用于为视图提供强类型的数据查询服务,否则我们就需要动态的ViewData或者ViewBag属性来实现。

视图的依赖注入

下面通过一个较完整的示例来讲解@using,@model和@inject指令的用法。

首先创建一个服务:

public interface IGreeter
{
string Greet(string firstname, string surname);
} public class Greeter : IGreeter
{
public string Greet(string firstname, string surname)
{
return $"Hello {firstname} {surname}";
}
} 

在Startup的服务容器中注册此服务:

public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IGreeter, Greeter>(); services.AddMvc();
}

创建一个模型:

public class AboutViewModel
{
public string Firstname { get; set; }
public string Surname { get; set; }
}

从控制器方法中返回模型实例:

public class HomeController : Controller
{
public IActionResult Index()
{
return View();
} public IActionResult AboutMe()
{
var model = new AboutViewModel
{
Firstname = "Tahir",
Surname = "Naushad"
};
return View("Bio", model);
}
}

现在我们可以在视图中使用模型和服务了:

@using RazorEngine.Models
@model AboutViewModel
@inject IGreeter GreeterService <p>@GreeterService.Greet(Model.Firstname, Model.Surname)</p>

运行,此时页面显示:

源代码下载

原文:https://tahirnaushad.com/2017/08/23/asp-net-core-2-0-mvc-razor/

[译]ASP.NET Core 2.0 视图引擎的更多相关文章

  1. [译]ASP.NET Core 2.0 路由引擎之网址生成

    问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...

  2. [译]ASP.NET Core 2.0 路由引擎

    问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...

  3. [译]ASP.NET Core 2.0 视图组件

    问题 如何在ASP.NET Core 2.0中使用视图组件? 答案 新建一个空项目,修改Startup类并添加MVC服务和中间件: public void ConfigureServices(ISer ...

  4. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  5. [译]ASP.NET Core 2.0 部分视图

    问题 如何在ASP.NET Core 2.0中使用部分视图来重用页面的公共部分? 答案 新建一个空项目,在Startup中添加MVC服务和中间件: public void ConfigureServi ...

  6. [译]ASP.NET Core 2.0 布局页面

    问题 如何在ASP.NET Core 2.0项目中共享可见元素.代码块和指令? 答案 新建一个空项目,首先添加GreetingService服务和UserViewModel模型: public int ...

  7. [译]ASP.NET Core 2.0 区域

    问题 如何将一个规模庞大的ASP.NET Core 2.0应用程序进行逻辑分组? 答案 新建一个ASP.NET Core 2.0空项目,修改Startup类,增加Mvc服务和中间件: public v ...

  8. [译]ASP.NET Core 2.0 中间件

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...

  9. [译]ASP.NET Core 2.0 带初始参数的中间件

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...

随机推荐

  1. CentOs下,配置tomcat支持https

    网上此类教程一大堆,本文主要记录步骤和几个注意点. 首先,我们使用jdk的keytool生成证书.命令如下: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: ...

  2. vim下处理文档中的\r\n\t字符

    问题复现 拿到的文档中包含了大量的\r.\n.\t等字符,形如: \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\ ...

  3. EGit使用教程:第一篇 添加工程到版本控制

    配置 确定身份 当每次提交的时候,Git需要跟踪这次提交,确认是哪个用户提交的.用户由 user.name 和 user.email 组成,这个信息包含在 ~/.gitconfig 文件中. ~ 代表 ...

  4. MongDB开启权限认证

    在生产环境中MongoDB已经使用有一段时间了,但对于MongoDB的数据存储一直没有使用到权限访问(MongoDB默认设置为无权限访问限制),最近在酷壳网看了一篇技术文章(https://cools ...

  5. URL编码解决

    与其他系统对接时遇到的问题URL中传递认证码,URL默认只允许传递ASCII码中的数据,所以浏览器默认会进行一次编码将%等特殊符号转义后台web服务器收到URL中的参数,会默认进行一次解码,但遇到的问 ...

  6. mybatis运行时错误Illegal argument exception argument type mismatch

    使用注解时遇到该错误 使用XML应该也会有相应的错误 解决办法:查看是不是Dao接口的参数列表没有加@Param注解  参数过多时需要该注解指明参数

  7. 运行Chromium浏览器缺少google api密钥无法登录谷歌账号的解决办法

    管理员身份运行CMD,然后依次输入以下三行内容: setx GOOGLE_API_KEY "AIzaSyAUoSnO_8k-3D4-fOp-CFopA_NQAkoVCLw"setx ...

  8. apollo实现c#与android消息推送(二)

    安装完成apache apollo后,org.eclipse.paho是很方便的测试软件,下来介绍paho的安装和使用 2. 搭建paho: a 下载 org.eclipse.paho.ui.app- ...

  9. Reverse Words in a String III

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  10. I/P/B/SI/SP帧和PTS/DTS的关系

    I frame:帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象.I帧可以看成是 ...