1. 模板项目一览
如果创建ASP.NET Core Web Application,目前官方预置了7种模板项目供我们选择。从中我们可以看出,既有我们熟悉的MVC、WebAPI,又新添加了Razor Page,以及结合比较流行的Angular、React前端框架的模板项目。基于给出的模板,我们可以根据自己的需求选择合适的模板搭建项目框架着手开发。同时,我们也可以基于提供的结合Angular、React客户端的模板项目来实施前后端分离的开发策略。
2. Empty 模板项目
我们先来看看创建的Empty模板项目结构:
从图中可以得知主要由以下几个部分组成:
- Dependencies:组织项目的依赖关系。从图中我们可以看到依赖被细化为三个类别:Analyzers、NuGet、SDK。其中NuGet是专门为.net设计的包管理器,组织从NuGet上安装的依赖项;SDK主要是Microsoft底层的系列依赖;其实还有另外几个类别:Projects、Bower、npm。Projects就是直接的项目依赖;Bower是专门为web设计的包管理器,用来组织web前端依赖;npm是专门为javascript设计的包管理器,用来组织javascript的相关依赖。
- Properties:其中仅包含launchSettings.json文件,该文件用于指定应用程序的启动设置。
- wwwroot:根目录,一般用来定义静态文件,如js、css、html、img、ico等等。
- Program:程序入口,其中定义了Main函数作为入口函数。从这一点可以看出,其实质是控制台应用。
- Startup:程序启动类。
2.1. 启动设置之launchSettings.json
首先该json文件中配置的属性可以参考launchSettings.json。
2.2. 入口函数之Main函数
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
ASP.NET Core应用程序需要由Host(宿主)进行管理,宿主为其提供运行环境并负责启动。所以Main函数主要是用来初始化宿主环境,而宿主环境的初始化需要借助WebHostBuilder。初始化完毕后,调用Run()方法来启动应用程序。
- WebHost.CreaateDefaultBuilder():创建WebHostBuilder。
- UseStartup<Startup>():指定启动类,用于依赖注入和中间件注册。
- Build():返回初始化完毕的IWebHost宿主。
- Run():启动WebHost。
2.3. 宿主构造器之WebHostBuilder
以上Program的简单几行代码,完成了一个应用程序的配置和启动。但简洁的代码不见得简单。我们结合源码来看一看。
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
return builder;
}
主要包含以下几个部分:
- UseKestrel:使用Kestrel作为Web server。
- UseContentRoot:指定Web host使用的content root(内容根目录),比如Views。默认为当前应用程序根目录。
- ConfigureAppConfiguration:设置当前应用程序配置。主要是读取 appsettinggs.json 配置文件、开发环境中配置的UserSecrets、添加环境变量和命令行参数 。
- ConfigureLogging:读取配置文件中的Logging节点,配置日志系统。
- UseIISIntegration:使用IISIntegration 中间件。
- UseDefaultServiceProvider:设置默认的依赖注入容器。
2.4. 启动类之Startup
public class Startup
{
// This method gets called by the runtime.
//Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime.
//Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
该类主要包括两个方法:
- ConfigureService:用于依赖服务注册。
- Configure:用于指定应用程序将如何响应每一个 HTTP 请求。一般用于注册中间件。
其中涉及到下以下几个可用服务:
- IServiceCollection:当前容器中各服务的配置集合,ASP.NET Core内置的依赖注入容器。
- IApplicationBuilder:用于构建应用程序的请求管道。
- IHostingEnvironment :提供了当前的 EnvironmentName、WebRootPath 以及 ContentRoot等。
2.5. 启动流程
首先我们需要明白,我们创建的.net core web application其实质是一个独立的控制台应用程序,不能直接处理Http请求,需要借助Web Server向外提供服务。.net core中默认使用内置的支持跨平台的Kestrel作为web server(当然还有其他web server可供选择,比如WebListener、Http.sys等等)。Web server是需要宿主环境来承载它。比如:Windows 上的IIS、Windows Services,Linux上的Apache、Nginx,或者Docker都可以作为Web Server的宿主。
而宿主就是用来负责启动我们的.net core 应用程序的。比如:IIS新增了一个 AspNetCoreModule 模块,它负责 ASP.NET Core 程序的启动与停止,并能监听 ASP.NET Core 程序的状态,在我们的应用程序意外崩溃时重新启动。
当仅仅是在内网中暴露服务的话,可以直接使用Kestrel处理http请求。否则,还是借助反向代理服务器(IIS、Nginx、Apache等)来转发http请求。但一般我们建议结合使用反向代理服务器来处理http请求,因为反向代理服务器可以在Kestrel之前做一些额外的处理(了解更多,可参考Introduction to Kestrel web server implementation in ASP.NET Core)。
通过以上的描述我们引入了Host与Server的概念。我们可以简单理解为host是一个进程用来管理应用程序,而server是用来暴露应用程序服务的。也可以理解为host是对server的一层包装。
3. MVC vs Razor Page
ASP.NET MVC 是一套基于Microsoft .NET Framework的用来开发web应用程序的开源框架。其基于关注点分离的思想将应用程序主要分为三个部分:Model、View、Controller。在ASP.NET Core中同样延续了MVC的优良设计。
在ASP.NET MVC中Razor作为一个高级视图引擎存在,Razor提供了一种新的标记语义,其大大减少了用户输入且具有表现力,主要的特点是使用@符号去书写标记。
而在ASP.NET Core中Razor不仅仅是一种视图引擎,其提供了一种新的页面设计方式——Razor Page。其主要的特点在于:
- 基于文件路径的路由系统;
- Razor Page类似于WebForm,一种MVVM的架构,支持双向绑定;
- Razor Page符合单一职责原则,每个页面独立存在,视图和代码紧密组织在一起。
4. MVC vs WebAPI
本质上的区别在于:ASP.NET MVC 用来创建web应用返回视图和数据;但是ASP.NET WEB API 是用来创建完整的HTTP服务,仅返回数据无视图返回。
就项目结构而言,差别如下:
5. Angualr 模板项目
我们可以借助Angular来开发SPA web应用,其结构就与MVC相比,主要多了ClientApp文件夹。其代码结构如下图所示:
6. 最后
关于模板项目的介绍就简要介绍到这里,我们后续在结合实际运用继续深入探讨!