问题

如何在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. 使用Lucene全文检索并使用中文版和高亮显示

    使用Lucene全文检索并使用中文版和高亮显示 中文分词需要引入 中文分词发的jar 包,咱们从maven中获取 <!-- lucene中文分词器 --> <dependency&g ...

  2. 教育,创新,提升:Indiegogo和Kickstarter上受中国用户支持的10个众筹项目

    中国的经济正在迅速发展,已成为世界第二大经济体.中国家庭随着经济水平的提高,越来越多父母愿意将自己的子女送到海外留学. 家长们希望自己的子女可以有机会接受国外大学优质的教育, 以便他们将来可以学成归来 ...

  3. 如何写一个jquery插件

      本文总结整理一下如何写一个jquery插件?虽然现今各种mvvm框架异常火爆,但是jquery这个陪伴我们成长,给我们带来很多帮助的优秀的库不应该被我们抛弃,写此文章,作为对以往欠下的笔记的补充, ...

  4. apollo实现c#与android消息推送(三)

    3 实现c#消息推送服务 c#实现消息推送必须引入M2Mqtt.dll,源码 a 连接apache apollo代理服务器的代码.需要引入using uPLibrary.Networking.M2Mq ...

  5. 1042 数字0-9的数量 1050 循环数组最大子段和 1062 序列中最大的数 1067 Bash游戏 V2 1092 回文字符串

    1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 给出一段区间a-b,统计这个区间内0-9出现的次数.   比如 10-19,1出现11次 ...

  6. Django的form表单之文件上传

    在生成input标签的时候可以指定input标签的类型为file类型 <!DOCTYPE html> <html lang="en"> <head&g ...

  7. 【技巧】datagrid锁定列后重新加载时出现错位问题的解决

    [问题描述]:有时候datagrid设置了锁定列后,在重新加载datagrid数据时,出现锁定列与非锁定列数据错位的问题,如图: [问题分析]:查看css样式我们发现,锁定的列和非锁定的列属于两个不同 ...

  8. OpenSCAD 建模:相框

    下载地址:https://github.com/ZhangGaoxing/openscad-models/tree/master/PhotoFrame 代码: module bottom(){ dif ...

  9. linux 内核 zImage 生成过程分析

    1. 依据arch/arm/kernel/vmlinux.lds 生成linux内核源码根目录下的vmlinux,这个vmlinux属于未压缩,带调试信息.符号表的最初的内核,大小约23MB: arm ...

  10. 关于使用连接器arm-linux-ld时指定链接地址的作用

    首先,记住一句话:程序的链接地址必须等于运行地址! 在学习exynos 4412的启动过程时,发现自己对链接地址的作用不是很了解,于是上网查找了资料做了基本了解,在此做个总结. 上图是exynos 4 ...