本文地址:https://www.cnblogs.com/oberon-zjt0806/p/12225807.html

O 前请提要

在第1期构建项目之后,我们看到项目中有这样的组成结构:

MyASPWebApplication/
├─obj/
│ └─/一些文件.../
├─Pages/
│ ├─Shared/
│ │ ├─_Layout.cshtml
│ │ └─_ValidationScriptsPartial.cshtml
│ ├─Error.cshtml
│ ├─Error.cshtml.cs
│ ├─Index.cshtml
│ ├─Index.cshtml.cs
│ ├─Privacy.cshtml
│ ├─Privacy.cshtml.cs
│ ├─_ViewImports.cshtml
│ └─_ViewStart.cshtml
├─Properties/
│ └─launchSettings.json
├─wwwroot/(empty)
├─appsettings.Development.json
├─appsettings.json
├─Program.cs
├─Startup.cs
└─MyASPWebApplication.csproj

这是初始生成项目所包含的目录结构,这里面包含了很多东西,但是,我们还不清楚每个部分能做些什么,充当怎样的一个角色,以及哪些东西是最基础的,这一节就来解决这些问题。

在第3期中我们从原理层面上了解了ASP.NET Core Web项目的一个基本的工作流程以及所包含的部分。

I 启动部分

I.1 Program

按照绝大部分C#开发框架的惯例,Program类一般是程序的入口,里面包含一个Main函数并被单独放置于Program.cs中。

小提示:

尽管C#并不像Java那样强制要求必须将各个数据实体分放到不同的文件中,但C#依然要求定义类的代码文件必须和该文件中所定义的类(如果多个则任取其一)相同。此外,如非必要,我们仍然建议将各个类定义分离到不同的文件中,除非:

  1. class Aclass B之间有比较大的实体关联,例如依赖关系。
  2. class B只是class A的一个辅助工具性的类,例如class B只是针对class A的一个异常类等

ASP.NET Core产生的Program类如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; namespace MyASPWebApplication
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

当然了,这里public static void Main(string[] args)自然就是程序的入口了。里面调用了他的下一个成员函数:

		public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});

这个函数的定义方式很特别,它使用了λ推演=>)的方式做的函数定义,但这无关紧要,实际上表达的是:

public static IHostBuilder CreateHostBuilder(string[] args)
{
IHostBuilder _ = Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults
(
webBuilder =>
{
webBuilder.UseStartup<Startup>();
}
)
return _;
}

这个函数主要调用了Host.CreateDefaultBuilder(args)静态函数使用程序的参数针对服务主机(Host)的进行一个默认配置。综上,Program类作为程序的入口,其所包含的配置内容大多面向于项目的顶层设施。

关于服务主机通用主机Web主机)的相关概念以及配置过程,在以后期介绍。

I.2 Startup

在上面的结构中,我们不得不注意的另外项目便是Startup.cs。当然了,本着C#的开发原则,我们很容易了解到这个代码文件中应当包含一个名为Startup的类。

Startup类位于当前项目的命名空间下(也就是说类全称为MyASPWebApplication.Startup)。这个类在项目被构建时被生成为这个样子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; namespace MyASPWebApplication
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
} app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}

I.2.1 这个类干什么呢??

如你所见,这个类并不继承于任一个其他的现有类,就是一个非常中规中矩的C#类。但事实上,这个类包含了这个Web应用程序被启动时执行的配置行为。

为什么一个普通的类就可以支配整个项目的配置呢?事实上,尽管被定义为一个普通的类,但Startup还是有一些特征的。

I.2.2 特征??

很明显,这个类的定义相当简单,除了构造函数外只有两个函数和一个只读属性:

public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

这两个成员函数的内容,表明了Startup的配置主要是两个方面:

  1. ConfigureServices函数以控制反转(IOC)的方式依赖注入(DI)项目中的 服务
  2. Configure函数负责配置请求应用管道

这里面出现了很多概念,比如管道、控制反转、依赖注入之类的,这将在之后期中慢慢解释。总之,这些内容是在WebApp运行期间被动态加载的配置。

而这个类最大的玄机在于,它在Program类中被引用过:

//---- Program.cs(节选) ----//
public static IHostBuilder CreateHostBuilder(string[] args)
{
IHostBuilder _ = Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults
(
webBuilder =>
{
webBuilder.UseStartup<Startup>();
}
)
}

第8行中,webBuilder.UseStartup<Startup>()就通过webBuilder加载了这个类作为默认的Host配置。这也正是为什么Startup作为一个普通的类就能够作为配置类的原因。

I.3 appsettings.json

终于,我们聚焦于不是C#类的一个主要文件了。这是一个json表格式的配置文件。

当然,我们实际上能看到两个文件:appsettings.jsonappsettings.Development.json。这两个文件的作用实际上没有什么实质性不同,只是应用的场合并不相同。当项目的运行环境为开发态(Development)的时候,优先使用appsettings.Development.json,否则使用另外一个。

初始状态下,appsettings.json的内容为:

{
"Logging":
{
"LogLevel":
{
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

这种文件里配置的内容多和数据有关。比如初始状态下有的"Logging"子表包含了对日志记录的配置信息。当然,又如当该WebApp使用数据库时,有关数据库的连接信息(连接字符串、超时等)也会被配置到这个json表中。

当然,在这张表中,我们也可以加入自己的配置信息,在程序中可以通过Microsoft.Extensions.Configuration.IConfiguration对象读取这个文件里的配置信息。

关于此文件中包含的配置项和配置方法也会在以后详细探索。

I.4 launchSettings.json

这个文件存在于Properties文件夹下,定义了项目的属性:

{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:64571",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyASPWebApplication": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

这个也属于配置文件,主要配置的是项目的运行环境,例如侦听端口等、环境模式、是否运行浏览器以及IIS反向代理的转发端口等。

比如,在这个配置模式下,当项目以IIS Express反向代理的方式运行时,就会访问http://localhost:64571,但如果不使用IIS而直接使用Kestrel来启动,那么项目地址就是http://localhost:5000

II wwwroot目录

另外一个比较显著的目录是wwwroot。如果使用Visual Studio创建项目,我们能够看到,这个wwwroot目录和Properties目录类似,有个特别的图标:

这里面目前是空的,不过这里一般用于放置静态文件(Static Files)。

II.1 静态文件??

说白了,就是在运行期间不会发生变化的,一般是指资源文件。

比如:静态网页(HTML)、静态样式表(CSS)、静态浏览器脚本(JS)、图片、音频等等等等。

wwwroot这个目录就是放这些东西进去的。

服务端处理这些静态文件是通过StaticFiles这一中间件组成的。

// ---- Startup.cs(节选) ---- //

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
} app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}

第14行就是Startup类中对此中间件的注册。

III 常规目录

为了使项目更为有序的组织,一些文件会被存放于一些目录(文件夹)中,而这些目录在ASP.NET Core下有约定的名称。

III.1 Pages目录和Views目录

Pages文件夹存放的内容被称为页面,这里用于存放Razor Pages开发模式下的Razor页面。

Razor Pages是ASP.NET Core 2.x中提出的一种新的开发模式,聚焦于页面,并以页面为中心。

MVC开发模式下,这个部分被替换为视图,存放于Views文件夹中。尽管两者之间有所不同,但我们目前要知道的是,这个文件夹里的东西聚焦于前端。

III.1.1 页面??但是wwwroot里不是也存放页面了么??

是的,但是wwwroot里面存放的是静态页面,而这里面存放的页面被称为Razor页面,是一种动态页面

III.1.2 有什么区别么??

当然有区别。虽然说这两者到浏览器客户端都会被解析为同样的东西,但是对于服务端而言,这两者有很大的区别。

存放于wwwroot中的页面简单来说就是写死的页面,这种页面无论运行多少次,服务端数据如何变化,其页面结果是不变的。

但动态页面是不一样的,动态页面是保留了一定不变内容基础之上又根据后端数据变化而被重新生成的。在浏览器上就被体现为,随着后台数据的变化,页面的显示结果会有所不同

III.1.3 Shared子文件夹

无论是Pages还是Views,因为都存放带有Razor标记的页面,所以这两个目录下往往还有一个子目录,称为Shared。这个目录主要存放的是共享的分部标记元素(我知道听不明白,以后会解释的)。

III.2 Controller文件夹

这个文件夹仅存在于MVC模式下,存放MVC模式当中的控制器(Controller,MVC中的C)。

控制器是一种特殊的类,ASP.NET Core中约定控制器类以Controller结尾。

在MVC中,控制器主要用于处理请求(Request)和路由(Routing)并提供响应。作用有些类似于Java中的Servlet。(具体内容和其他概念的以后介绍,以后介绍)

III.3 Models文件夹

如果WebApp关联了数据库,那么数据库中的数据必然存在一种数据模型,这种数据模型在关系理论中称为关系模式,它实际上与面向对象理论中的是对应的。

一般来说因为数据库的数据组织方式和应用中组织方式的这种不同,因此在项目中处理这些数据就必须自己编写数据访问(DA)功能将数据库中的关系元组转化成应用可以使用的类对象,但是一个Web项目中的数据门类非常的多,这也就造成了关系模式也非常的多,要编写的内容也就非常的多,那么为了统一地、自动地处理和显示这些数据,减轻重复编码的负担,一种称为对象关系映射(ORM)的数据开发模式就产生了。

ORM的机制使得我们只需要在程序中写出数据模型(类定义),而无需提供存取方法(这个由ORM提供,这个过程也被称为数据绑定)。那么Models目录就是为了存放这些数据模型的。

IV 其他

除了上面这些之外,还有其他的东西,遇到再说。

To be continued ...

初探ASP.NET Core 3.x (4) - 项目的重要组成的更多相关文章

  1. ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package

    目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我 ...

  2. ASP.NET Core 2.0 : 三. 项目结构

    本章我们一起来对比着ASP.NET Framework版本看一下ASP.NET Core 2.0的项目结构.(此后的文章也尽量这样对比着, 方便学习理解.) 关注差异, 也为项目迁移做准备. 新建项目 ...

  3. ASP.NET Core Web多语言项目

    公司效益好了,准备和国外做生意,这个时候就需要多语言了. > 1. 这是一个ASP.NET Core Web多语言项目,主要展示项目的不同: > 2. 第一种:www.xxx.com/en ...

  4. Taurus.MVC 微服务框架 入门开发教程:项目集成:2、客户端:ASP.NET Core(C#)项目集成:应用中心。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  5. 简读《ASP.NET Core技术内幕与项目实战》之3:配置

    特别说明:1.本系列内容主要基于杨中科老师的书籍<ASP.NET Core技术内幕与项目实战>及配套的B站视频视频教程,同时会增加极少部分的小知识点2.本系列教程主要目的是提炼知识点,追求 ...

  6. 快读《ASP.NET Core技术内幕与项目实战》EFCore2.5:集合查询原理揭秘(IQueryable和IEnumerable)

    本节内容,涉及4.6(P116-P130).主要NuGet包:如前述章节 一.LINQ和EFCore的集合查询扩展方法的区别 1.LINQ和EFCore中的集合查询扩展方法,虽然命名和使用完全一样,都 ...

  7. 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践

    本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...

  8. 《ASP.NET Core技术内幕与项目实战》精简集-目录

    本系列是杨中科2022年最新作品<ASP.NET Core技术内幕与项目实战>及B站配套视频(强插点赞)的精简集,是一个读书笔记.总结和提炼了主要知识点,遵守代码优先原则,以利于快速复习和 ...

  9. ASP.NET Core 2.0 MVC项目实战

    一.前言 毕业后入职现在的公司快有一个月了,公司主要的产品用的是C/S架构,再加上自己现在还在学习维护很老的delphi项目,还是有很多不情愿的.之前实习时主要是做.NET的B/S架构的项目,主要还是 ...

随机推荐

  1. P1012 鸡兔同笼问题

    题目描述 笼子里有鸡和兔若干,一直它们共有头 \(n\) 个,有脚 \(m\) 只,问笼中的鸡和兔共有多少只? 输入格式 输入包含两个整数 \(n,m(1 \le n \le 100, 2n \le ...

  2. NetBIOS 计算机名称命名限制

    本文告诉大家对于 NetBIOS 的命名的限制 长度限制 最小长度是 1 最长长度是 15 因为默认是 16 字符,但是微软使用最后一个字符作为后缀 可以使用的字符 可以使用英文和数字 abcdefg ...

  3. 51nod 1282 时钟

    1282 时钟  题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形的,P个刻度均分 ...

  4. records

    2019年数据地址备份: three.js 实例在NextWebProject/static/canvas下边! qlgj 在NextWebProject下边!

  5. node-sass安装报错

    npm install --save-dev node-sass --registry=https://registry.npm.taobao.org --disturl=https://npm.ta ...

  6. CMD操纵Mysql命令大全

    连接:mysql -h主机地址 -u用户名 -p用户密码 (注:u与root可以不用加空格,其它也一样)断开:exit (回车) 创建授权:grant select on 数据库.* to 用户名@登 ...

  7. C# 实现多线程

    1.System.Threading命名空间 System.Threading命名空间提供了使得可以多线程编程的类和接口   其中 (1)Thread类构成了C#多线程编程的支柱,他用于创建并控制线程 ...

  8. 关于hibernate5的映射文件和配置文件改变(转)

    转自:https://blog.csdn.net/m0_37840000/article/details/78823716 配置文件: <!DOCTYPE hibernate-configura ...

  9. Visio常规图表

    包含的就是一些形状模块 比如框图就包含了“方块”以及“具有凸起效果的块”两个形状模版 打开visio 新建的时候选择常规类别 具有透视效果的框图 下面是基本操作: 这是自动调整大小的框 不能调整大小 ...

  10. JVM 体系结构与工作方式

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...