[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
由于ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,所以在它上面构建的应用开发框架都是建立在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是建立在用来实现路由的EndpointRoutingMiddleware和EndpointMiddleware中间件上。ASP.NET Core MVC利用路由系统为它分发请求,并在此基础上实现针对目标Controller的激活、Action方法的选择和执行,以及最终对于执行结果的响应。在介绍的实例演示中,我们将对上面创建的ASP.NET Core作进一步改造,使之转变成一个MVC应用。
一、注册服务与中间件
ASP.NET Core框架内置了一个原生的依赖注入框架,该框架利用一个依赖注入容器提供管道在构建以及请求处理过程中所需的服务,而这些服务需要在应用启动的时候被预先注册。对于ASP.NET Core MVC框架来说,它在处理HTTP请求的过程中所需的一系列服务同样需要预先注册。对这个概念有了基本的了解之后,相信读者朋友们对如下所示的代码就容易理解了。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; namespace helloworld
{
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder
.ConfigureServices(servicecs => servicecs
.AddRouting()
.AddControllersWithViews())
.Configure(app => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapControllers())))
.Build()
.Run();
}
}
}
整个ASP.NET MVC框架建立在EndpointRoutingMiddleware和EndpointMiddleware中间件构建的路由系统上,这两个中间件采用“终结点(Endpoint)映射”的方式实现针对HTTP请求的路由。这里所谓的终结点可以视为应用程序提供的针对HTTP请求的处理器,这两个终结点通过预先设置的规则将具有某些特征的请求(比如路径、HTTP方法等)映射到对应的终结点,进而实现路由的功能。对于一个MVC应用程序来说,我们可以将定义在Controller类型中的Action方法视为一个终结点,那么路由映射最终体现在HTTP请求与目标Action方法的映射上。
如上面的代码片段所示,我们先后调用了IApplicationBuilder接口的UseRouting和UseEndpoints扩展方法注册了EndpointRoutingMiddleware和EndpointMiddleware中间件。在调用UseEndpoints方法的时候,我们利用指定的Action<IEndpointRouteBuilder>委托对象调用了IEndpointRouteBuilder接口的MapControllers扩展方法完成了针对定义在Controller类型中所有Action方法的映射。
由于注册的中间件具有对其他服务的依赖,我们需要预先将这些服务注册到依赖注入框架中。依赖服务的注册通过调用IWebHostBuilder的ConfigureServices方法来完成,该方法的参数类型为Action<IServiceCollection>,添加的服务注册就保存在IServiceCollection接口表示的集合中。在上面的演示程序中,两个中间件依赖的服务是通过调用IServiceCollection接口的AddRouting和AddControllersWithViews方法进行注册的。
如下所示的HelloController是我们定义的Controller类型。按照约定,所有的Controller类型名称都应该以“Controller”字符作为后缀。与之前版本的ASP.NET MVC不同,ASP.NET Core MVC下的Controller类型并不要求强制继承某个基类。我们在HelloController中定义了一个唯一的Action方法SayHello,该方法直接返回一个内容为“Hello World”的字符串。
public class HelloController
{
[HttpGet("/hello")]
public string SayHello() => "Hello World.";
}
我们在Action方法SayHello上通过标注的HttpGetAttribute特性注册了一个模板为“/hello”的路由,意味着请求地址为“/hello”的GET请求最终会被路由到这个Action方法上,而该方法执行的结果将作为请求的响应内容。所以启动该程序后使用浏览器访问地址“http://localhost:5000/hello”,我们依然会得到如下图所示的输出结果。

二、引入视图
上面这个程序并没有涉及视图,所以算不上一个典型的MVC应用,接下来我们对它做进一步改造。为了让HelloController具有视图呈现的能力,我们让它派生于基类Controller。Action方法SayHello的返回类型被修改为IActionResult接口,它表示Action方法执行的结果。我们为该方法定义了一个表示姓名的参数name,通过HttpGetAttribute特性注册的路由模板(“/hello/{name}”)中具有与之对应的路由参数。换句话说,满足该路径模式的请求URL携带的姓名将自动绑定到该Action方法的name参数上。在SayHello方法中,我们利用ViewBag将代表姓名的name参数值传递给呈现的视图,该方法最终调用View方法返回当前Action方法对应的ViewResult对象。
public class HelloController : Controller
{
[HttpGet("/hello/{name}")]
public IActionResult SayHello(string name)
{
ViewBag.Name = name;
return View();
}
}
由于我们调用View方法时没有显式指定视图的名称,所以视图引擎会将当前Action的名称(“SayHello”)作为视图的名称。如果该视图还没有经过编译(部署时针对View的预编译,或者在这之前针对该View的动态编译),视图引擎将从若干候选的路径中读取对应的.cshtml 文件进行编译,其中首选的路径为“{ContentRoot}\Views\{ControllerName}\{ViewName}.cshtml”。为了迎合视图引擎定位视图文件的规则,我们需要将SayHello对应的视图文件(SayHello.cshtml)定义在目录“\Views\Hello\”下。

如下所示的就是SayHello.cshtml这个文件的内容,这是一个针对Razor引擎的视图文件。从文件的扩展名(.cshtml)我们看出可以这样的文件可以同时包含HTML标签和C#代码。总的来说,视图文件会在服务端生成最终在浏览器呈现出来的HTML,我们可以在这个文件中直接提供原样输出的HTML标签,也可以内嵌一段动态执行的C#代码。虽然Razor引擎对View文件的编写制定了严格的语法,但是我个人觉得没有必要在Razor语法上花太多的精力,因为Razor语法的目的就是让我们很“自然”地将动态C#代码和静态HTML标签结合起来,并最终生成一份完整的HTML文档,因此它的语法和普通的思维基本是一致。比如下面这个View最终会生成一个完整的HTML文档,其主体部分只有一个<p>标签。该标签的内容是动态的,因为包含利用ViewBag从Controller传进来的姓名。
<html>
<head>
<title>Hello World</title>
</head>
<body>
<p>Hello, @ViewBag.Name</p>
</body>
</html>
再次运行该程序后,我们利用浏览器访问地址“http://localhost:5000/hello/foobar”。由于请求地址与Action方法SayHello上的路由规则相匹配,所以路径携带的姓名(foobar)会绑定到该方法的name参数上,所以我们最终将在浏览器上得到如下图所示的输出结果。

三、使用Startup类型
任何一个ASP.NET Core应用在初始化的时候都会根据请求处理的需求注册对应的中间件。在前面演示的实例中,我们都是直接调用IWebHostBuilder的Configure扩展方法来注册所需的中间件,但是在大部分真实的开发场景中我们一般会将中间件以及依赖服务的注册定义在一个单独的类型中。按照约定,我们通常会将这个类型命名为Startup,比如我们演示实例中针对服务和中间件的注册就可以放在如下定义的这个Startup类中。
public class Startup
{
public void ConfigureServices(IServiceCollection services) => services
.AddRouting()
.AddControllersWithViews(); public void Configure(IApplicationBuilder app) => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapControllers());
}
如上面的代码片段所示,我们不需要让Startup类实现某个预定义的接口或者继承某个预定义基类,所采用的完全是一种基于“约定”的定义方式。随着对ASP.NET Core框架认识的加深,我们会发现这种“约定优于配置”的设计广泛地应用在整个框架之中。按照约定,服务注册和中间件注册分别实现在ConfigureServices和Configure方法中,它们的第一个参数类型分别为IServiceCollection和IApplicationBuilder接口。由于已经将两种核心的操作转移到了Startup类型中,所以我们需要注册该类型。Startup类型可以调用IWebHostBuilder接口的UseStartup<TStartup>扩展方法进行注册。
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder.UseStartup<Startup>())
.Build()
.Run();
}
}
我们在前面的内容中对.NET Core、ASP.NET Core以及ASP.NET Core MVC应用的编程作了初步的体验,但是这仅仅限于我们熟悉的Windows平台。作为一个号称跨平台的开发框架,我们有必要在其他操作系统平台上体验一下.NET Core开发的乐趣。
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Linux
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Docker
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]的更多相关文章
- [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
由于ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,所以在它上面构建的应用开发框架都是建立在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是建立在用来实 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
我们在<上篇>利用dotnet new命令创建了一个简单的控制台程序,接下来我们将它改造成一个ASP.NET Core应用.一个ASP.NET Core应用构建在ASP.NET Core框 ...
- [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
我们在<上篇>利用dotnet new命令创建了一个简单的控制台程序,接下来我们将它改造成一个ASP.NET Core应用.一个ASP.NET Core应用构建在ASP.NET Core框 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Docker
对于一个 .NET Core开发人员,你可能没有使用过Docker,但是你不可能没有听说过Docker.Docker是Github上最受欢迎的开源项目之一,它号称要成为所有云应用的基石,并把互联网升级 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Linux
如果想体验Linux环境下开发.NET Core应用,我们有多种选择.一种就是在一台物理机上安装原生的Linux,我们可以根据自身的喜好选择某种Linux Distribution,目前来说像RHEL ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS
除了微软自家的Windows平台, .NET Core针对Mac OS以及各种Linux Distribution(RHEL.Ubuntu.Debian.Fedora.CentOS和SUSE等)都提供 ...
- 《ASP.NET Core 3框架揭秘》博文汇总
在过去一段时间内,写了一系列关于ASP.NET Core 3相关的文章,其中绝大部分来源于即将出版的<ASP.NET Core 3框架揭秘>(博文只能算是"初稿",与书 ...
随机推荐
- 2019-10-9:渗透测试,基础学习,php文件上传,mysql基础
header("Content-Type:text/html;charst="utf-8")设置头部信息,解决编码问题setcookie("loginStrin ...
- 新闻实时分析系统 Spark2.X环境准备、编译部署及运行
1.Spark概述 Spark 是一个用来实现快速而通用的集群计算的平台. 在速度方面, Spark 扩展了广泛使用的 MapReduce 计算模型,而且高效地支持更多计算模式,包括交互式查询和流处理 ...
- Android利用碎片fragment实现底部标题栏(Github模板开源)
在安卓开发当中,一个十分重要的布局则是底部标题栏了,拥有了底部标题栏,我们就拥有了整个软件UI开发的框架,一般而言,整个软件的布局首先就是从底部标题栏开始构建,然后再开始其他模块的编写,组成一个完善的 ...
- SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".错误的解决方法
1.今天新git下来的项目报错如下: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: ...
- 1. Python 基础概述 和 环境安装
目录 Python 推荐书籍 开发环境 - Pyenv pyenv 使用 设置Python版本 virtualenv 虚拟环境 pip 通用配置 pip导出和导入 Jupyter 安装和配置 安装 j ...
- 配置aria2
Mac 用户肯定都受够了百度网盘在自己电脑上的糟糕体验,至少我是如此:安装官方的 App,经常下载时中断,有时甚至 Bug 般连续中断,无奈使用浏览器下载,速度却是令人挠头.花点时间来配置 aria2 ...
- SMProxy,让你的数据库操作快三倍!
SMProxy GITHUB:https://github.com/louislivi/smproxy 喜欢请star 中文 | English /$$$$$$ /$$ /$$ /$$$$$$$ /$ ...
- 程序计数器(PC)、堆栈指针(SP)与函数调用过程
PC(program counter)是CPU中用于存放下一条指令地址的寄存器,SP为堆栈指针.下面将介绍函数调用过程中CPU对PC和SP这两个寄存器的操作. 假设有如下函数Fun Fun() { … ...
- 洛谷 P3420 [POI2005]SKA-Piggy Banks 题解
蒟蒻的第二篇题解 嗯,直接进入正题 先告诉你们这是并查集,好吧,标签上面有,再来分析这为什么是并查集. 根据题意: 每一个存钱罐能够用相应的钥匙打开或者被砸开,Byteazar已经将钥匙放入到一些存钱 ...
- poi-tl二次开发
poi-tl二次开发 poi-tl是一款非常好用的word模板生成库,更新响应快.文档demo齐全.堪称word模板界的小军刀! 写在前面 如果你对word模板技术有了解.或者有兴趣,更甚者工作中接触 ...