章节

第一章:https://blog.51cto.com/kimiliucn/7010307

第二章:https://blog.51cto.com/kimiliucn/7040822

第三章:https://blog.51cto.com/kimiliucn/7040820


五、创建项目+Seesion传值

5.1-使用Session

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数


5.2-Log4Net组件使用

(1)管理Nuget程序,下载【log4net】和【Microsoft.Extensions.Logging.Log4Net.AspNetCore】

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_02

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_03

(2)新建一个文件夹,保存log4net配置文件,一定要在【属性】中的 复制到输出目录 选择【始终复制】。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_04

(3)在【Program.cs】文件的【CreateHostBuilder】方法中配置log4net。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_05

也可以使用以下方式配置(在Startup中):这里注意,别选择错了!然后就可以了。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_06


六、程序的发布运行

6.1-项目的发布

(1)右击项目,选择【发布】

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_07

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_08

(2)选择【文件夹】

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_09

(3)选择要保存的路径,然后点击【完成】;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_10

(4)点击【发布】,可以看到已经发布完成了。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_11

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_12


6.2-项目的运行

6.2.1-IIS发布

  • IIS直接简历网站,目录指向项目跟目录下的Debug、Net5文件;——不行
  • 把项目发布后,目录指向项目发布目录;——可以的


6.2.2-ASP.NET Core跨平台原因

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_13


6.2.3-使用脚本启动网站

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_14

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_15


6.2.4-发布之后运行为什么样式加载不出404?

(1)需要在【startup.cs】文件的【Configure】方法中引入一个中间件。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_16


七、命令参数读取+配置多种读取

7.1-配置文件读取(1)

在【startup.cs】文件中读取配置文件

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_17

在【控制器】中读取配置文件。

(1)先构造函数注入Configure

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_18

(2)写代码获取

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_19

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_20


7.2-配置文件读取(2)

(1)定义一个类,结构(数据类型、属性名)和配置文件中完全一致。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_21

(2)在【Startup.sc】配置一下

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_22

(3)在控制器中,构造函数注入一个IOptions

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_23

(4)获得并返回值

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_24

(5)前端获取值

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_25

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_26


八、MVC开发

8.1-什么是MVC?
  • V——View——视图:呈现给用户看到的内容(表现层)
  • C——Controller——控制器:控制业务逻辑计算,调用服务,选择返回什么内容,可以返回视图,JSON、字符串等等。
  • M——Model——视图模型:用作控制器和视图之间传递数据的载体。


8.2-cshtml文件

其实是一个类文件。

Razor混编:可以在cshtml上写 后台C#代码 + 前台html代码,混合起来写;

(1)可以引入命名空间

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_27

(2)直接写后台代码

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_28

(3)实现接口

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_29

(4)可以依赖注入

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_30

(5)可以添加特性Class

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_31

(6)定义方法并调用

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_32

(7)写单行代码、多行代码

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_33

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_34

(8)Razor表达式

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_35

(9)输出尖括号

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_36

(10)for循环

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_37

(11)在后台代码内部写HTML代码

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_38

8.3-如何解决修改视图后无需编译后即可生效?

修改视图,增加了html代码,不能马上生效,怎么办?使用中间件

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_39

1.引入Nuget包

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_40

2.在【Startup.cs】文件的票【ConfigureServices】方法中配置。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_41


8.4-Razor布局

8.4.1-我们看到的页面组成到底有哪些内容?
答:包含了Layout的模板嵌套的返回的需要渲染的视图内容;


8.4.2-如何嵌套呢?

答:通过Layout中RendBody()方法做了替换;把返回的视图替换到模板也中,形成了一整块的内容;目的在于每一次返回不同的页面的时候,能够吧不变的视图部分,种以重用;这样就可以少些代码。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_42


8.4.3-在模板页面导入了JQ,在视图页面使用JQ为什么报错?
注意:

  • 在模板页中使用CSS/JS的时候,为了提高效率,会把Css引入在模板的上方,将JS写在模板的下方。页面嵌套到模板页后,就会出现在引用JS的上方调用JS,此时JS其实是调用不了的。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_43

答:因为Script是写在下面的,先加载RenderBody,后加载JQ,所以会报错,解决方法如下:

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_44


九、Razor扩展-HTML控件

9.1-Html扩展控件(1)

本质:通过一个后台方法,返回一个【已经存在】的Html标签的字符串,浏览器在读取的时候,就读取成一个Html标签。

1.定义

/// <summary>
        /// 图片
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="src"></param>
        /// <returns></returns>
        public static IHtmlContent Img(this IHtmlHelper helper,string src,string @class)
        {
            return new HtmlString($"<img src='{src}'  class='{@class}'/>");
        }

2.调用

<!--1.引入命名空间-->

<!--2.使用图片--自定义 扩展方法-->
@Html.Img("https://tpc.googlesyndication.com/simgad/3105023548593992165/downsize_200k_v1?w=200&h=200","border:1px solid red;")


9.2-Html扩展控件(2)

通过一个后台方法,返回一个【不存在】的Html标签的字符串,在读取的时候,通过制后台方法,去生成我们制定的标签。

1.写一个扩展方法,定义一个普通类,类名建议以TagHelper结尾,加上特性;如果没有标记特性,视图中在调用的时候使用当前类名去掉TagHelper后缀得到的的字符串来调用。继承TagHelpre抽象类、或者实现接口ITagHelpr,二者选一起均可。然后实现接口Proccss方法。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_45

2.在【_ViewImports.cshtml】进行注册

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_46

3.使用

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_47


9.3-Razor局部视图

1.创建一个局部视图

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_48


2.进行调用

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_49


9.3.1-局部视图的缺陷:
局部视图没有去访问控制器中的Action,所以不能完美的实现后台代码。可以使用视图组件解决。


9.4-视图组件-扩展定制

9.4.1-视图组件的优点?

  • 呈现页面相应的某一部分而不是整个相应
  • 包括在控制器和视图之间发现的关注分离和可测试性优势
  • 可以具有参数和业务逻辑
  • 通常在页面布局中调用


9.4.2-如何自定义视图组件?

(1)Rzaor组件对应的类需要以ViewComponent结尾,该类需要继承自ViewCompnent类。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_50

(2)定义一个异步版本的InvokeAsync,可以自定义参数,IncokeAsync就是返回组件内容的方法。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_51

(3)在Views/Shared文件下建立Components文件夹,在这个文件下创建一个和组件类名相同(如果加了特性,就按照特性上面的名称来)的文件夹,然后创建一个Default.cshtml视图。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_52

注意:以上步骤可以不按照上面执行,我们可以随意新建一个视图,然后指定路径就可以了。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_53

(4)调用

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_54


十、内置容器基本使用

10.1-什么是IOC?

把对象的创建,统一交给第三方容器来创建;


10.2-如何使用IOC?

(1)在【Startup.cs】的【ConfigureServices】中注册服务;注册抽象和具体的依赖关系;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_55

(2)通过构造函数进行依赖注入,自动得到服务的实例;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_56

(3)调用;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_57


10.3-如何使用IOC?(第二种方法)

(1)在【Startup.cs】的【ConfigureServices】中注册服务;注册抽象和具体的依赖关系;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_58

(2)通过构造函数进行依赖注入。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_59

(3)调用;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_60


10.4-在视图中使用IOC

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_61


10.4-什么是依赖注入?

DI依赖注入:IServiceCollection支持且支持构造函数注入。
如对象A依赖对象B,对象B依赖于对象C,就可以先构造对象C,然后传递给对象B,然后传递给对象A,然后得到具体的实例。可以支持无限层级的依赖注入,前提是先要先注入服务(注册抽象和具体的映射关系)。


10.5-IServiceCollection生命周期

那么在创建对象的时候, 不同的情况,需要让对象单例,每一次都创建新的对象实例,不同的作用于创建新的实例。

AddTransient:顺时声明周期,每次获取的都是不同的实例

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_62

AddSingleton:单例生命周期,在整个进程中获取的都是同一个实例

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_63

AddScoped:作用域生命周期(同一个作用域,获取的是同一个对象的实例,不同的作用域,获取的是不同的独对象实例)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_64

建议:开发工作中,一般情况下,都是一个请求一个对象的实例,所以使用的是顺时声明周期(AddTransient)。


十一、Autofac容器

11.1-Autofac容器初识?

Autofac也是一款流行的IOC容器;


11.2-如何使用Autofac容器?

(1)管理Nuget程序包,下载并安装【Autofac】

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_65

(2)在【Startup.cs】的【ConfigureServices】中注册服务;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_66


11.3-Autofac注入方式-构造函数注入

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_67

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_68


11.4-Autofac注入方式-属性注入

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_69

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_70


11.5-Autofac注入方式-方法注入

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_71

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_72


11.6-Autofac生命周期-瞬时生命周期(默认)

瞬时生命周期:每一次获取对象都是一个全新的实例,默认的生命周期。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_73


11.7-Autofac生命周期-单例生命周期

单例声明周期:在整个进程中,对象永远都是同一个实例(SingleInstance)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_74


11.8-Autofac生命周期-每个生命周期范围一个实例

每个生命周期范围一个实例:同一个生命周期范围内是同一个实例,不同的生命周期范围,实例不一样。(InstancePerLifetimeScope)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_75


11.9-Autofac生命周期-每个匹配生命周期范围一个实例

语法:InstancePerMatchingLifetimeScope(名称)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_76


11.10-Autofac生命周期-每个请求一个实例

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_77


11.11-Autofac支持配置文件

(1)管理Nuget包,引入3个程序集;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_78

(2)新建一个配置文件【autofac.json】,记得将配置文件设置为:始终复制到目录。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_79

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_80

(3)在【Startup.cs】的【ConfigureServices】中注册服务;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_81


11.12-Autofac整合MVC

注意:Autofac是一个第三方容器;

(1)指定Autofac工厂替换默认工厂,在【Program.cs】中的【CreateHostBuilder】方法中指定。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_82

(2)在【Startup.cs】类中增加一个【ConfigureContainer】方法,用来注册服务关系。

/// <summary>
/// 增加一个方法:
/// 整个方法被Autofac自动调用
/// 负责注册各种服务
/// </summary>
/// <param name="services"></param>
public void ConfigureContainer(ContainerBuilder containerBuilder) {
    containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>();
    containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>();
    containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>();
    containerBuilder.RegisterType<TestServiceD>().As<ITestServiceD>().PropertiesAutowired();
    containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>();
}

(3)通过控制器构造函数注入,获取实例。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_83

这种方法也还能用:

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_84


11.13-Autofac支持控制器属性注入

(1)首先在【Startup.cs】中【ConfigureServices】方法中,指定控制器实例容器来创建,进行替换。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_85

(2)创建一个类(特性);

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_86

(3)创建一个类,用来判断维度;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_87

(4)在【Startup.cs】中创建一个【ConfigureContainer】方法,负责注册各种服务。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_88


11.14-Autofac一个实例多实现的问题

注意:

  • 如果一个抽象多个实例,都注册了,通过构造函数用抽象类型来获取实例,哪个是后面注册的,就能获得哪个,覆盖类型的。
  • 如果一个抽象多个实例,都注册了,可以通过一个IEnumerable<抽象类>,当做构造函数参数,可以获取到左右注册的具体的实例。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_89

一般使用以下方法:

(1)在【Startup.cs】中创建的【ConfigureContainer】方法中,注册资源和实现(单抽象、多实现)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_90

(2)通过构造函数中,使用具体理性实理性做我参数,可以匹配到不同的具体类型实例。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_91

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_92


(1)新建一个类,该类继承Module类,实现Load方法。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_93


(2)与之前相同,不同的而方式:在【Startup.cs】中创建的【ConfigureContainer】方法中,注册资源和实现(单抽象、多实现)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_94


11.15-Autofac通过抽象(接口)支持AOP(面向切面编程-做应用型系统)

AOP-面向切面编程:不用修改之前代码的基础上,可以动态的在某个动作之前加一些操作,动态的在某一个动作之后做点什么事。

(1)管理Gurget程序包,下载【Castle.Core】包,该包用来动态代理。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_95

(2)创建一个类为【CustomAutofacAop】,该类继承自【IInterceptor】接口,并实现接口中的【Intercept】方法。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_96

(3)在服务的抽象上面做一个标记,这个标记是用来:支持AOP扩展能够生效。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_97


(4)因为这个【CustomAutofacAop】实例也是通过Autofac的IOC来做的,所以需要在【Startup.cs】中创建的【ConfigureContainer】方法中,注册服务,让Autofac支持AOP。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_98


11.16-Autofac通过类支持AOP

(1)管理Gurget程序包,下载【Castle.Core】包,该包用来动态代理。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_99

(2)创建一个类为【CustomAutofacAopClass】,该类继承自【IInterceptor】接口,并实现接口中的【Intercept】方法。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_100

(3)在类上面做一个标记,这个标记是用来:支持AOP扩展能够生效。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_101

(4)因为这个【CustomAutofacAop】实例也是通过Autofac的IOC来做的,所以需要在【Startup.cs】中创建的【ConfigureContainer】方法中,注册服务,让Autofac支持AOP。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_102


11.17-Autofac单抽象多实现构造函数注入(MVC)

(1)在【Startup.cs】中创建的【ConfigureContainer】方法中,注册服务。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_103

(2)在控制器中调用。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_104


11.18-Autofac单抽象多实现属性注入

(1)道理和上面是一样的,可以吧Autofac上下文当做属性来注入。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_105

(2)在使用的时候,通过Autofac上下文+不同注册的标识,获取到不同的具体实例。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_106


十二、Filter过滤器

12.1-.NET5中5个Filter
  • AuthorizationFilter:鉴权授权
  • ResourceFilter:资源
  • ExceptionFilter:异常
  • ActionFilter:方法
  • ResultFilter:结果


12.2-ActionFilter

1.自定义一个CusotmActionFilterAttribute

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_107

2.将特性标记在控制器中的某个方法上。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_108


3.执行顺序如下:

  • 执行控制器构造函数
  • 执行CusotmActionFilterAttribute类的OnActionExecuting()方法
  • 执行Action
  • 执行CusotmActionFilterAttribute类的OnActionExecuted()方法


12.3-ActionFilter的多种使用

1.通过实现IActionFilter接口来完扩展

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_109


2.通过继承ActionFilterAttribute(系统提供的实现),根据不同的方法,达到自己的需求。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_110


3.异步版本的实现,通过实现IAsyncActionFilter接口来实现。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_111


12.4-ActionFilter的应用(日志处理)+依赖注入

1.做记录日志;ActionFilter比较靠近Action,日志记录就可以记录到Action内部做的一些处理。

(1)通过Log4net完成日志记录,需要注入Logger。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_112


12.5-Filter的多种注入和特点

(1)[CustomActionFilter]:Filter必须是无参数构造函数

(2)[TypeFilter(typeof(CusotmLogFilterAttribute))]:可以没有无参数构造函数,可以支持依赖注入。

(3)  [ServiceFilter(typeof(CusotmLogFilterAttribute))]:可以没有无参数构造函数,可以支持依赖注入。但是如果要使用这个,必须在【Startup.cs】中创建的【ConfigureContainer】方法中,注册服务注册一下;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_113


.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_114


(4)问:依赖注入是如何支持的?

答:IOC来做到的


12.6-ServiceFilter_TypeFilter的原理/扩展定制FilterFacoty

1.为什么可以使用ServiceFilter/TypeFilter都可以支持依赖注入呢?--是IOC容器来完成。

(1)自定义一个特性类,继承Attribute,实现接口IFilterFactory,实现接口中的方法;通过构造函数传递需要实例化的特性的Type类型;在实现接口中,通过Type获取到实例;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_115

(2)标记在Action中。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_116


12.7-Filter生效范围和控制执行顺序

12.7.1-Filter生效范围

  • 标记在Action上,就只对当前Action生效。
  • 标记在Controller上,就对改Controller上所有的Action生效。
  • 全局注册,对于当前整个项目中的Actioin都生效(在【Startup.cs】中创建的【ConfigureServices】方法中进行全局注册)。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_117


12.7.2-Filter的执行顺序

问:如果有三个ActionFilter,分别注册全局、控制器、Action;执行顺序如何呢?

答:先执行全局——>控制器——>Action——>控制器——>全局

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_118

可以理解为俄罗斯套娃。


12.7.3-改变Filter的执行顺序

(1)将全局、控制器、Action的类继承自ActionFilterAttribute;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_119

(2)使用是传入Order参数,值越小越先执行。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_120


12.7.4-在自定义扩展中改变Filter的执行顺序

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_121


12.7-ResourceFilter扩展定制做缓存(为缓存而生)

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_122

(1)自定义一个特性类,继承Attribute,实现接口IResourceFilter,实现接口中的方法;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_123

(2)标记在Action中;

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_124


12.8-Filter匿名

问题:如果全局注册,Filter生效于所有的Action,如果有部分Action我希望你不生效,怎么办呢?
匿名:可以避开Filter的检查;

如何支持自定义的Filter匿名:

(1)自定义一个特性类,继承Attribute。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_125


(2)需要在需要匿名的Filter内部,检查是否需要匿名(检查是否标记的有匿名特)如果有就避开。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_生命周期_126

(3)使用Action。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_127


12.9-ExceptionFilter-异常处理

(1)自定义一个CustomExceptionAttribute,继承Attribute,实现IExceptionFilter接口。

  • 实现方法,先判断,异常是都被处理过,如果没有被处理过,就处理。
  • 分情况处理:1.如果是ajax请求,就返回JsonReulst,如果不是Ajax,就返回错误页面。
public class CustomExceptionAttribute : Attribute, IExceptionFilter
 {
        private readonly IModelMetadataProvider _modelMetadataProvider = null;
        /// <summary>
        /// 依赖注入:Model元数据的驱动
        /// </summary>
        public CustomExceptionAttribute(
            IModelMetadataProvider modelMetadataProvider
            ) {
            _modelMetadataProvider = modelMetadataProvider;
        }

        /// <summary>
        /// 当异常发生的时候出发到这里来
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            //判断异常有没有被处理过
            if (context.ExceptionHandled == false) {
                //没有处理过,在这里开始处理

                //如果是Ajax请求(看看Header是不是XMLHttpRequest)
                if (this.IsAjaxRequest(context.HttpContext.Request))
                {
                    //中断式:如果对Result赋值,请求到这里结束了,不在继续Action
                    context.Result = new JsonResult(new
                    {
                        Result = false,
                        Msg = context.Exception.Message
                    });
                }
                else {
                    //跳转到异常页面
                    var result = new ViewResult { ViewName = "~/Views/Errors.cshtml" };
                    result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState);
                    result.ViewData.Add("Exception", context.Exception);
                    result.ViewData.Add("ErrDate", DateTime.Now);
                    //中断式:如果对Result赋值,请求到这里结束了,不在继续Action
                    context.Result = result;
                }
                context.ExceptionHandled = true;//指定异常已经被处理了
            }
        }

        /// <summary>
        /// 判断是不是Ajax请求
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private bool IsAjaxRequest(HttpRequest request)
        {
            string header = request.Headers["X-Requested-With"];
            return "XMLHttpRequest".Equals(header);
        }
    }

(2)注册到Action上,只对Action生效。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_ASP.NET Core_128

一般不会注册到Action上,一般会注册到全局(在【Startup.cs】中创建的【ConfigureServices】方法中进行全局注册)。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_129

问题:ExceptionFilter能捕捉到哪些异常?能捕获到所有异常吗?


12.10-ExceptionFilter-异常捕捉覆盖
  • 控制器实例化异常——能
  • 异常发生在Try-cache中——不能,因为异常已经被捕捉到了
  • 在视图中发生异常——不能
  • 在Service层(业务逻辑层)中发生异常——能
  • 在Action中发生异常——能
  • 请求错误路径异常——不能(但是可以通过中间件解决)

在【Startup.cs】中创建的【Configure】方法中进行使用,只要状态不是200,就可以处理。

#region 捕捉异常的补充
            //只要不是200,都能进来
            app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");

            app.UseExceptionHandler(errorApp => {
                errorApp.Run(async context =>
                {
                    context.Response.StatusCode = 200;
                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
                    await context.Response.WriteAsync("Error!!!<br><br>\r\n");
                    var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();

                    Console.WriteLine("------------------------------------------------");
                    Console.WriteLine($"{ exceptionHandlerPathFeature?.Error.Message}");
                    Console.WriteLine("------------------------------------------------");

                    if (exceptionHandlerPathFeature?.Error is FileNotFoundException) {
                        await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
                    }

                    await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
                    await context.Response.WriteAsync($"<p>{ exceptionHandlerPathFeature?.Error.Message}</p><br>\r\n");
                    await context.Response.WriteAsync("</body></html>\r\n");
                    await context.Response.WriteAsync(new string(' ', 512));//IE padding

                });
            });
#endregion


12.11-ReusltFilter-结果Filter

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Autofac_130

(1)创建ResultFilter

自定义一个CustomResultFilterAttribute,继承Attribute,实现IResultFilter接口

public class CustomResultFilterAttribute : Attribute, IResultFilter
  {
        /// <summary>
        /// 在渲染视图之前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine("在喧嚷视图之前执行");
        }

        /// <summary>
        /// 渲染视图之后执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine("渲染视图之后执行");
        }
    }

(2)在Action上标记、使用

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_Startup_131


12.11-ReusltFilter应用-开发双语言系统功能

双语言系统其实就需要两个视图,要根据语言的不同,来选择不同的视图;因为在渲染视图之前,会进入到OnResultExecuting方法,就可以在这个方法中确定究竟使用哪一个视图文件。

.NET5从零基础到精通:全面掌握.NET5开发技能【第二章】_构造函数_132


上一章节:https://blog.51cto.com/kimiliucn/7010307

下一章节:https://blog.51cto.com/kimiliucn/7040820


版权声明:本文为原创文章,版权归 [西瓜程序猿] 所有,转载请注明出处,有任何疑问请私信咨询。

原文链接:https://blog.51cto.com/kimiliucn/7040822