原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kingyumao/article/details/81532745

二、创建项目

1.选择【文件】→【新建】→【项目】

2.新建一个名称为CoreBackend.Api的【.NET Core】的【ASP.NET Core Web 应用程序】

二.1 解读项目生成的代码 Program.cs

这个Program是程序的入口, 看起来很眼熟, 是因为asp.net core application实际就是控制台程序(console application).

它是一个调用asp.net core 相关库的console application. 
Main方法里面的内容主要是用来配置和运行程序的.

因为我们的web程序需要一个宿主, 所以 CreateWebHostBulider这个方法就创建了一个WebHostBuilder. 而且我们还需要Web Server.
Build()完之后返回一个实现了IWebHost接口的实例(WebHostBuilder), 然后调用Run()就会运行Web程序, 并且阻止这个调用的线程, 直到程序关闭.
UseStartup<Startup>(), 这句话表示在程序启动的时候, 我们会调用Startup这个类.

看一下WebHost.CreateDefaultBuilder(args)的源码:

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;
}

asp.net core 自带了两种http servers, 一个是WebListener, 它只能用于windows系统, 另一个是kestrel, 它是跨平台的.

kestrel是默认的web server, 就是通过UseKestrel()这个方法来启用的.

但是我们开发的时候使用的是IIS Express, 调用UseIISIntegration()这个方法是启用IIS Express, 它作为Kestrel的Reverse Proxy server来用.

如果在windows服务器上部署的话, 就应该使用IIS作为Kestrel的反向代理服务器来管理和代理请求.

如果在linux上的话, 可以使用apache, nginx等等的作为kestrel的proxy server.

当然也可以单独使用kestrel作为web 服务器, 但是使用iis作为reverse proxy还是由很多有点的: 例如,IIS可以过滤请求, 管理证书, 程序崩溃时自动重启等.

二.2 解读项目生成的代码 Startup.cs

其实Startup算是程序真正的切入点.

ConfigureServices方法是用来把services(各种服务, 例如identity, ef, mvc等等包括第三方的, 或者自己写的)加入(register)到container(asp.net core的容器)中去, 并配置这些services. 这个container是用来进行dependency injection的(依赖注入). 所有注入的services(此外还包括一些框架已经注册好的services) 在以后写代码的时候, 都可以将它们注入(inject)进去. 例如上面的Configure方法的参数, app, env, loggerFactory都是注入进去的services.

Configure方法是asp.net core程序用来具体指定如何处理每个http请求的, 例如我们可以让这个程序知道我使用mvc来处理http请求, 那就调用app.UseMvc()这个方法就行. 但是目前, 所有的http请求都会导致返回"Hello World!".

这几个方法的调用顺序: Main -> ConfigureServices -> Configure

请求管道和中间件(Request Pipeline, Middleware)

请求管道: 那些处理http requests并返回responses的代码就组成了request pipeline(请求管道).
中间件: 我们可以做的就是使用一些程序来配置那些请求管道 request pipeline以便处理requests和responses. 比如处理验证(authentication)的程序, 连MVC本身就是个中间件(middleware).

每层中间件接到请求后都可以直接返回或者调用下一个中间件. 一个比较好的例子就是: 在第一层调用authentication验证中间件, 如果验证失败, 那么直接返回一个表示请求未授权的response.
app.UseDeveloperExceptionPage(); 就是一个middleware, 当exception发生的时候, 这段程序就会处理它. 而判断env.isDevelopment() 表示, 这个middleware只会在Development环境下被调用.

可以在项目的属性Debug页看到这个设置: 



需要注意的是这个环境变量Development和VS里面的Debug Build没有任何关系.

在正式环境中, 我们遇到exception的时候, 需要捕获并把它记录(log)下来, 这时候我们应该使用这个middleware: Exception Handler Middleware, 我们可以这样调用它:

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
}



UseExceptionHandler是可以传参数的, 但暂时先这样, 我们在app.Run方法里抛一个异常, 然后运行程序, 在Chrome里按F12就会发现有一个(或若干个, 多少次请求, 就有多少个错误)500错误.

用来创建 Web Api的middleware:

 原来的.net使用asp.net web api 和 asp.net mvc 分别来创建 web api和mvc项目. 但是 asp.net core mvc把它们整合到了一起.

MVC Pattern

model-view-controller 它的定义是: MVC是一种用来实现UI的架构设计模式. 但是网上有很多解释, 有时候有点分不清到底是干什么的. 但是它肯定有这几个有点: 松耦合, Soc(Separation of concerns), 易于测试, 可复用性强等.

但是MVC绝对不是完整的程序架构, 在一个典型的n层架构里面(presentation layer 展示层, business layer 业务层, data access layer数据访问层, 还有服务处), MVC通常是展示层的. 例如angular就是一个客户端的MVC模式.

在Web api里面的View就是指数据或者资源的展示, 通常是json.

注册并使用MVC

因为asp.net core 2.0使用了一个大而全的metapackage, 所以这些基本的services和middleware是不需要另外安装的.

首先, 在ConfigureServices里面向Container注册MVC: services.AddMvc();

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); // 注册MVC到Container
}

然后再Configure里面告诉程序使用mvc中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
} app.UseMvc();
}



注意顺序, 应该在处理异常的middleware后边调用app.UseMvc(), 所以处理异常的middleware可以在把request交给mvc之间就处理异常, 更重要的是它还可以捕获并处理返回MVC相关代码执行中的异常.

然后别忘了把app.Run那部分代码去掉. 然后改回到Develpment环境, 跑一下, 试试效果:

Chrome显示了一个空白页, 按F12, 显示了404 Not Found错误.

这是因为我只添加了MVC middleware, 但是它啥也没做, 也没有找到任何可用于处理请求的代码, 所以我们要添加Controller来返回数据/资源等等.

Asp.net Core 2 Metapackage 和 Runtime Store

Asp.net core 2 metapackage, asp.net core 2.0开始, 所有必须的和常用的库也包括少许第三方库都被整和到了这个大而全的asp.net core 2 metapackage里面, 所以开发者就不必自己挨个库安装也没有版本匹配问题了.

Runtime Store, 有点像以前的GAC, 在系统里有一个文件夹里面包含所有asp.net core 2程序需要运行的库(我电脑的是: C:\Program Files\dotnet\store\x64\netcoreapp2.0), 每个在这台电脑上运行的asp.net core 2应用只需调用这些库即可. 

它的优点是:

部署快速, 不需要部署这里面包含的库;

节省硬盘空间, 多个应用程序都使用同一个store, 而不必每个程序的文件夹里面都部署这些库文件. 

程序启动更快一些. 因为这些库都是预编译好的.

缺点是: 服务器上需要安装.net core 2.0以上

但是, 也可以不引用Runtime Store的库, 自己在部署的时候挨个添加依赖的库.

 

从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目的更多相关文章

  1. 从零开始学习 asp.net core 2.1 web api 后端api基础框架(三)-创建Data Transfer Object

    原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(三)-创建Data Transfer Object 版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...

  2. 从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller

    原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  3. 从零开始学习 asp.net core 2.1 web api 后端api基础框架(一)-环境介绍

    原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(一)-环境介绍 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.ne ...

  4. 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 webservice/API

    2018 .NET开发者调查报告: .NET Core 是怎么样的状态,这里我们看到了还有非常多的.net开发人员还在观望,本文给大家一个建议.这仅代表我的个人意见, 我有充分的理由推荐.net 程序 ...

  5. [01]从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍

    从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新 ...

  6. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. 从明面上学习ASP.NET Core

    一.前言     这篇文章就是从能看到地方去学习Core,没有很深奥,也没有很难懂,现在我们开始吧. 二.构建项目,引发思考     创建项目的步骤真的很简单,你要是不会,我真也没法了,我这是创建的M ...

  8. 从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板

    标题:从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11155 ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

    标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/112 ...

随机推荐

  1. Hadoop集群日常运维 分类: A1_HADOOP 2015-03-01 21:26 502人阅读 评论(0) 收藏

    (一)备份namenode的元数据 namenode中的元数据非常重要,如丢失或者损坏,则整个系统无法使用.因此应该经常对元数据进行备份,最好是异地备份. 1.将元数据复制到远程站点 (1)以下代码将 ...

  2. 用Eclipse替代Keil&IAR来开发ARM应用(升级版)

    Eclipse GNU ARM Plugin 2014/7/16 作者 kiya 几个月前写了一篇<),想自己丰衣足食的参考我的上一篇文章,以及GNU ARM的官网. 用Eclipse替代Kei ...

  3. SpringMvc中两个Controller类之间传递参数的方法

    使用SpringMvc框架,在访问ControllerA的时候,将A里面的参数传递到ControllerB中.适用于同一框架下两个不同Controller或者由rpc(dubbo)连接的两个工程里的C ...

  4. LIGO找到首个超越广义相对论的证据?

    转自 麻省理工科技评论 原文 LIGO找到首个超越广义相对论的证据? 1915年,爱因斯坦根据简单的原理提出广义相对论,极大地改变了人们的时空观.广义相对论不仅解释了牛顿理论无法解释的现象,还做出许多 ...

  5. udacity android 实践笔记: lesson 4 part a

    udacity android 实践笔记: lesson 4 part a 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  6. ENVI显示GDAL创建GeoTiff文件的一个问题及其思考

    作者:朱金灿 来源:http://blog.csdn.net/clever101 使用gdal创建一个100*100的红色的geotiff图像,代码如下: #include <assert.h& ...

  7. Windows Phone 8.1 数据处理

    Windows Phone 8.1 应用的数据存储位置包括: Installation Folder ApplicationData Credential Locker Known Folders S ...

  8. 200行代码,7个对象——让你了解ASP.NET Core框架的本质

    原文:200行代码,7个对象--让你了解ASP.NET Core框架的本质 2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘&g ...

  9. 【u015】兽径管理

    [问题描述] 约翰农场的牛群希望能够在 N 个(1<=N<=200)草地之间任意移动.草地的编号由 1到N.草地之间有树林隔开.牛群希望能够选择草地间的路径,使牛群能够从任一 片草地移动到 ...

  10. thinkphp中如何实现无限级分类?

    thinkphp中如何实现无限级分类? 一.总结 1.数据表设计+递归算法 二.php实现无限级分类实例总结 1.数据库数据如下: 2.任务需求:给一个id,求自己和所有父亲. 3.实现代码如下:th ...