[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]

因为ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,因此在它上面构建的应用开发框架都是创建在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是创建在用来实现路由的EndpointRoutingMiddlewareEndpointMiddleware中间件上。ASP.NET Core MVC利用路由系统为它分发请求,并在此基础上实现针对目标Controller的激活、Action方法的选择和执行,以及最终对于执行结果的响应。在介绍的实例演示中,咱们将对上面建立的ASP.NET Core做进一步改造,使之转变成一个MVC应用。html

1、注册服务与中间件

ASP.NET Core框架内置了一个原生的依赖注入框架,该框架利用一个依赖注入容器提供管道在构建以及请求处理过程当中所需的服务,而这些服务须要在应用启动的时候被预先注册。对于ASP.NET Core MVC框架来讲,它在处理HTTP请求的过程当中所需的一系列服务一样须要预先注册。对这个概念有了基本的了解以后,相信读者朋友们对以下所示的代码就容易理解了。web

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框架创建在EndpointRoutingMiddlewareEndpointMiddleware中间件构建的路由系统上,这两个中间件采用“终结点(Endpoint)映射”的方式实现针对HTTP请求的路由。这里所谓的终结点能够视为应用程序提供的针对HTTP请求的处理器,这两个终结点经过预先设置的规则将具备某些特征的请求(好比路径、HTTP方法等)映射到对应的终结点,进而实现路由的功能。对于一个MVC应用程序来讲,咱们能够将定义在Controller类型中的Action方法视为一个终结点,那么路由映射最终体如今HTTP请求与目标Action方法的映射上。编程

如上面的代码片断所示,咱们前后调用了IApplicationBuilder接口的UseRoutingUseEndpoints扩展方法注册了EndpointRoutingMiddleware和EndpointMiddleware中间件。在调用UseEndpoints方法的时候,咱们利用指定的Action<IEndpointRouteBuilder>委托对象调用了IEndpointRouteBuilder接口的MapControllers扩展方法完成了针对定义在Controller类型中全部Action方法的映射。浏览器

因为注册的中间件具备对其余服务的依赖,咱们须要预先将这些服务注册到依赖注入框架中。依赖服务的注册经过调用IWebHostBuilder的ConfigureServices方法来完成,该方法的参数类型为Action<IServiceCollection>,添加的服务注册就保存在IServiceCollection接口表示的集合中。在上面的演示程序中,两个中间件依赖的服务是经过调用IServiceCollection接口的AddRoutingAddControllersWithViews方法进行注册的。服务器

以下所示的HelloController是咱们定义的Controller类型。按照约定,全部的Controller类型名称都应该以“Controller”字符做为后缀。与以前版本的ASP.NET MVC不一样,ASP.NET Core MVC下的Controller类型并不要求强制继承某个基类。咱们在HelloController中定义了一个惟一的Action方法SayHello,该方法直接返回一个内容为“Hello World”的字符串。app

public class HelloController { [HttpGet("/hello")] public string SayHello() => "Hello World."; }

咱们在Action方法SayHello上经过标注的HttpGetAttribute特性注册了一个模板为“/hello”的路由,意味着请求地址为“/hello”的GET请求最终会被路由到这个Action方法上,而该方法执行的结果将做为请求的响应内容。因此启动该程序后使用浏览器访问地址“http://localhost:5000/hello”,咱们依然会获得以下图所示的输出结果。框架

1-7

2、引入视图

上面这个程序并无涉及视图,因此算不上一个典型的MVC应用,接下来咱们对它作进一步改造。为了让HelloController具备视图呈现的能力,咱们让它派生于基类Controller。Action方法SayHello的返回类型被修改成IActionResult接口,它表示Action方法执行的结果。咱们为该方法定义了一个表示姓名的参数name,经过HttpGetAttribute特性注册的路由模板(“/hello/{name}”)中具备与之对应的路由参数。换句话说,知足该路径模式的请求URL携带的姓名将自动绑定到该Action方法的name参数上。在SayHello方法中,咱们利用ViewBag将表明姓名的name参数值传递给呈现的视图,该方法最终调用View方法返回当前Action方法对应的ViewResult对象。ide

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\”下。ui

1-12

以下所示的就是SayHello.cshtml这个文件的内容,这是一个针对Razor引擎的视图文件。从文件的扩展名(.cshtml)咱们看出能够这样的文件能够同时包含HTML标签和C#代码。总的来讲,视图文件会在服务端生成最终在浏览器呈现出来的HTML,咱们能够在这个文件中直接提供原样输出的HTML标签,也能够内嵌一段动态执行的C#代码。虽然Razor引擎对View文件的编写制定了严格的语法,可是我我的以为没有必要在Razor语法上花太多的精力,由于Razor语法的目的就是让咱们很“天然”地将动态C#代码和静态HTML标签结合起来,并最终生成一份完整的HTML文档,所以它的语法和普通的思惟基本是一致。好比下面这个View最终会生成一个完整的HTML文档,其主体部分只有一个<p>标签。该标签的内容是动态的,由于包含利用ViewBag从Controller传进来的姓名。spa

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <p>Hello, @ViewBag.Name</p>
  </body>
</html>

再次运行该程序后,咱们利用浏览器访问地址“http://localhost:5000/hello/foobar”。因为请求地址与Action方法SayHello上的路由规则相匹配,因此路径携带的姓名(foobar)会绑定到该方法的name参数上,因此咱们最终将在浏览器上获得以下图所示的输出结果。

1-13

3、使用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框架认识的加深,咱们会发现这种“约定优于配置”的设计普遍地应用在整个框架之中。按照约定,服务注册和中间件注册分别实如今ConfigureServicesConfigure方法中,它们的第一个参数类型分别为IServiceCollectionIApplicationBuilder接口。因为已经将两种核心的操做转移到了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

原文出处:https://www.cnblogs.com/artech/p/inside-asp-net-core-01-03.html

相关文章
相关标签/搜索