项目结构和程序入口

已按固定格式整理完成,以下为 WordPress 可复制排版内容:

09-内容根目录和网站根目录以及配置

应用程序所有内容的的根路径。通过就是我们通过dotnet new 创建的项目名称目录。

网站根目录

类似CSS JS 图片 等静态文件的目录

静态文件中间件默认只读取web根目录和其子目录。

web根目录默认为 《内容根目录》/wwwroot

当然可以通过配置WebHostBuilder来指定另外一个地址。

比如我们拷贝一张图片到wwwroot下面的images

http://localhost:51543/images/063253ndtt5i8siierdtrt.jpg 那么访问这张图片 就是这个地址

而不是 http://localhost:51543/wwwroot/images/063253ndtt5i8siierdtrt.jpg

那是因为我们的静态文件 都交给了这个静态中间件

静态中间件 检查 发现是静态文件 那么它之间处理了

配置

asp.net core的配置 不再基于System.Configuration 或者web.config

它是一个有序拉去数据的配置 providers

它支持多种文件格式 xml json ini

(大家想想 问什么这样?)

我觉得应该是为了跨平台 因为config文件 应该linux 或苹果系统 可能不支持

10-了解Application Startup

Startup是应用程序的入口

这个类可以设置配置,将应用程序将要使用的服务连接起来。

可以在Startup类中配置请求管道。该管道可以处理应用程序 所有的请求。

操作系统-main-startup

Startup类

应用程序的入口,所有应用程序都有该类

ASP.NET 会在主程序集中搜索Startup类(可以是任何命名空间)

当然可以通过配置Hosting:Appliction 配置项 来指定搜索其他的程序集

ASP.NET 不关心Startup类是public

只要符合命名规范

另外如果有多个Startup 也不会报异常 知识ASP.NET 会选择其中一个

下面说说它的两个方法

Configure方法

指定应用程序 将如何处理每一个Http请求。

Configure方法 必须接受一个Iapplicationbuilder方法

也可以将其他的服务器注入进来。比如

如果把configure方法 改为configure1等其他方法

再语法上面 不会报错 但是运行时候 就会报下面异常

An error occurred while starting the application.
InvalidOperationException: A public method named 'ConfigureDevelopment' or 'Configure' could not be found in the 'MvcDemo.Startup' type.
Microsoft.AspNetCore.Hosting.Internal.StartupLoader.FindMethod(Type startupType, string methodName, string environmentName, Type returnType, bool required)
InvalidOperationException: A public method named 'ConfigureDevelopment' or 'Configure' could not be found in the 'MvcDemo.Startup' type.
Microsoft.AspNetCore.Hosting.Internal.StartupLoader.FindMethod(Type startupType, string methodName, string environmentName, Type returnType, bool required)
Microsoft.AspNetCore.Hosting.Internal.StartupLoader.FindConfigureDelegate(Type startupType, string environmentName)
Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider hostingServiceProvider, Type startupType, string environmentName)
Microsoft.AspNetCore.Hosting.WebHostBuilderExteCode language: PHP (php)

ConfigureDevelopment 这个作为configure的方法名 也是可以的

如果把configureservice改为其他名称 那么就会报下面的异常 并且是注册mvc中间件抛出的

System.InvalidOperationException:“Unable to find the required services. Please add all the required services by calling 'IServiceCollection.AddMvc' inside the call to 'ConfigureServices(...)' in the application startup code.”Code language: JavaScript (javascript)

所以 就是 必须注册服务 才能注册中间件 有一些中间件 比如mvc

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //如果是开发环境
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        //加入错误页跳转
        app.UseExceptionHandler("/Home/Error");
    }

    //使用静态文件
    app.UseStaticFiles();

    //使用MVC
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}Code language: JavaScript (javascript)

Use***扩展方法

每个Use扩展方法都会把一个中间件加入请求管道。例如UseMVC 加入路由中间件请求管道。

后面我们会介绍更多的中间件

app.UseStaticFiles();

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});Code language: JavaScript (javascript)

这里 就是当一个地址请求过来 到达管道 那么管道 先交给静态中间件来处理 静态中间件如果发现 是静态文件 并且能够处理 那么就返回这个文件 就比如我们这个图片 如果不是静态文件 那么 就交给下一个中间件 就是这里的mvc中间件 mvc中间件 是一个路由 然后这个路由就去匹配这个地址 如果能够匹配得了 那么 就交给mvc来处理 就会取执行控制器的action 然后视图 否则 就会继续往下

app 有很多 usexxx的方法

很多是扩展方法 用来注册中间件

app是IApplicationBuilder

ConfigureService方法

通过IserviceCollection 进行更多的配置。

比如配置数据库连接

配置Identity

配置MVC

配置EF

比如我们下面

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}Code language: JavaScript (javascript)

通过依赖注入将服务加入到容器中。

11-补充Startup讲解-在启动时加载服务Run方法的短路问题

asp.net core启动期间 提供一些应用服务和对象。使用这些服务非常简单,只需要在Startup构造函数和Configue ConfigureService方法中包含合适的接口即可。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)Code language: JavaScript (javascript)

Configure的参数类型

下面是Startup类中对每个方法可用的服务:

  • IApplicationBuilder(用于构建应用程序的请求管道,只能在Configure方法中用)
  • IApplicationEnvironment 提供了访问应用程序的属性 比如ApplicationName ApplicationVersion 等
  • IHostingEnvironment 提供EnvironmentName WebRootPath 和Web根文件提供者。(Configure方法中用)
  • IIloggerFactory 提供创建 日志的机制 构造函数或者Configure中用

中间件

中间件用于组件应用程序管道来处理请求和响应的组件。管道内每一个组件都可以选择是否将请求交给下一个组件。并可以在组件中 进行执行下一个程序之前的操作。

请求委托被用来建立请求管道,请求委托处理每一个Http请求。

app.Run(HandleHtml);//run方法会导致短路 也就是不会再往下传递 所以最好放在底部
app.UseStaticFiles();Code language: JavaScript (javascript)

这样 任何的地址 都会只返回handlerHtml返回的代码,连图片也是

http://localhost:51543/images/063253ndtt5i8siierdtrt.jpg

还可以这样来注册Run

app.Run(async context => { await context.Response.WriteAsync("www.FoxDevelop.com  FoxDevelop.com"); });Code language: JavaScript (javascript)

12-Configure中的Map方法使用

请求管道通过IApplicationBuilder的Run Map已经Use扩展方法来配置。并在Startup类中传给Configure方法。每个单独的请求委托都可以被指定为一个内嵌匿名方法,或者定义一个可重用的类中。这个可重用的类被称为”中间件”或者中间组件。

正常的路径 还是可以访问到 比如mvc 部分,然后静态还是可以处理的。然后只要匹配到地址是/helper 那么就会被我们的handlerHelpr处理了 然后和他是run 所以就中断了

app.Map("/helper", HandlerHelper);Code language: JavaScript (javascript)

然后处理函数

/// <summary>
/// map到/help方法的处理函数
/// </summary>
/// <param name="app"></param>
private void HandlerHelper(IApplicationBuilder app)
{
    app.Run(async context => { await context.Response.WriteAsync("----help me----");  });
}Code language: JavaScript (javascript)

一但访问/helper方法 就不会进入mvc里面的 因为已经被handler拦截了

ASP.NET 请求管道由一系列的请求委托所组成。他们一个接一个被调用,如图。

每个委托在下一个委托之前和之后 都有机会执行操作。任何委托都可以选择不传递给下一个委托 比如图片最后一个。这个就是请求的短路 这个很有意义 可以避免不必要的工作。比如一个授权中间件 只有通过身份认证才能访问下一个委托 否则会被短路 并返回 无权访问提示。

下面是Configure方法默认增加的中间件:错误处理、静态文件服务器、身份认证、MVC。

理解中间件

Run map use这些方法 可以配置HTTP管道

Run会短路管道 因为它不会调用next请求,所以Run一般放在底部。

ASP.NET CORE提供的中间件

13-中间件的实践-自定义中间件-记录访客IP-顺便学习日志

  1. 创建一个空白 web项目
  2. 安装Microsoft.Extensions.Logging.Console
  3. nuget
Install-Package Microsoft.Extensions.Logging.ConsoleCode language: CSS (css)
PM> Install-Package Microsoft.Extensions.Logging.Console
  GET https://api.nuget.org/v3/registration3-gz-semver2/microsoft.extensions.logging.console/index.json
  OK https://api.nuget.org/v3/registration3-gz-semver2/microsoft.extensions.logging.console/index.json 347 毫秒
正在还原 E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\WebApplication3\WebApplication3\WebApplication3.csproj 的包...
正在安装 NuGet 程序包 Microsoft.Extensions.Logging.Console 2.0.1。
正在提交还原...
将锁定文件写入磁盘。路径: E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\WebApplication3\WebApplication3\obj\project.assets.json
E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\WebApplication3\WebApplication3\WebApplication3.csproj 的还原在 482.42 ms 内完成。
执行 nuget 操作花费时间 2.29 sec
已用时间: 00:00:03.8585221
PM>Code language: JavaScript (javascript)

新建一个RequestIPMiddleware.cs

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebApplication3
{
    public class RequestIPMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public RequestIPMiddleware(RequestDelegate next,ILoggerFactory loggerFactory)
        {
            _next = next;
            _logger = loggerFactory.CreateLogger<RequestIPMiddleware>();
        }

        public async Task Invoke(HttpContext context)
        {
            _logger.LogInformation("User IP" + context.Connection.RemoteIpAddress.ToString());
            await _next.Invoke(context);
        }
    }
}Code language: PHP (php)

再新建一个RequestIPExtension.cs扩展方法

using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebApplication3
{
    public static class RequestIPExtension
    {
        public static IApplicationBuilder UseRequestIP(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestIPMiddleware>();
        }
    }
}Code language: JavaScript (javascript)

Startup中注册,使用中间件

public void ConfigureDevelopment1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    loggerFactory.AddConsole(minLevel: LogLevel.Information);//配置日志级别
    app.UseRequestIP();//调用岗顶定义的扩展方法
}Code language: JavaScript (javascript)

asp.net core 控制台查看日志

CMD中输入,先cd到项目的csproj所在目录,输入 dotnet run 回车

C:\Users\YY>e:

E:\>cd E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\Source\DemoIPRecordLogging\WebApplication3

E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\Source\DemoIPRecordLogging\WebApplication3>dotnet run
从 E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\Source\DemoIPRecordLogging\WebApplication3\Properties\launchSettings.json 使用 启动设置...
Hosting environment: Development
Content root path: E:\FoxDevelop.com视频\137-ASP.NET CORE 视频教程\Source\DemoIPRecordLogging\WebApplication3
Now listening on: http://localhost:57630
Application started. Press Ctrl+C to shut down.Code language: JavaScript (javascript)

当我们运行程序 访问 http://localhost:57629/ 的时候,可以看到控制台中输出。但是发现 没有日志输出 其实我们的日志监听的是 http://localhost:57630/ 这个端口 从cmd命令行中可以看到。所以 我们访问 http://localhost:57630/ 后发现如下输出。

参考:https://blog.csdn.net/jjjjj102310253/article/details/78654216

这集课的代码

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DemoLogging.Cores
{
    public class RequestIPMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public RequestIPMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            _next = next;
            _logger = loggerFactory.CreateLogger<RequestIPMiddleware>();
        }

        public async Task Invoke(HttpContext context)
        {
            _logger.LogInformation("用户IP:" + context.Connection.RemoteIpAddress.ToString());
            //两种方式传递下去 一是invoke 一个直接next
            //await _next.Invoke(context);
            await _next(context);
            _logger.LogInformation("回来时间:" + DateTime.Now.ToString());
        }
    }
}Code language: JavaScript (javascript)

然后在startup中 app.UseMiddleware<RequestIPMiddleware>(); 注入中间件。我们发现 我们的中间件 还记录了很多其他的css 以及图片的 地址。

我们把MVC中间件去掉,或者我们在mvc前 加入run 使得中间件短路 不再执行mvc的中间件

app.UseMiddleware<RequestIPMiddleware>();

//他会把mvc中断了 所以就只会返回www.FoxDevelop.com 这样我们的日志就清晰 就不会有mvc中的其他静态文件 比如css 图片的请求
app.Run(async (context) => { await context.Response.WriteAsync("www.FoxDevelop.com"); });Code language: JavaScript (javascript)

注意 日志控制台监听的端口是比程序运行的端口+1的 一般

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注