diff --git "a/\347\231\275\345\251\211\345\251\267/20240523.md" "b/\347\231\275\345\251\211\345\251\267/20240523.md" deleted file mode 100644 index 6ecd2faa90d99e8978a6cb8d44fe50c19e31606c..0000000000000000000000000000000000000000 --- "a/\347\231\275\345\251\211\345\251\267/20240523.md" +++ /dev/null @@ -1,143 +0,0 @@ -### 一、将简单的api转换为控制器模式的写法(Api写法) -1. program.cs部分代码 -![pro-2024-5-2322:17:56.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/pro-2024-5-2322:17:56.png) -2. Startup.cs部分代码 -![startup-2024-5-2322:17:48.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/startup-2024-5-2322:17:48.png) -3. HelloController.cs代码不变 - -### 二、依赖注入 -#### 1.简介 -- 组件与组件之间存在依赖关系,但是但一方不存在时,另一方就不能正常工作,这个时候就需要采用控制反转。 -- 控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度,其中最常见的方式叫做依赖注入,也可以说依赖注入和控制反转是一回事 -- 依赖注入的方式主要有三种: - - 构造函数注入 - - 属性注入:通过在需要注入的类中声明属性 - - 方法注入:将依赖项通过方法参数传递的方式进行依赖注入 -#### 2.举例说明 -~~~js - // MyDependency.cs - public class MyDependency - { - public void WriteMessage(string message) - { - Console.WriteLine($"调用的数据为{message}"); - } - } - - // IndexModel.cs - public class IndexModel - { - // 假设在当前类中需要引用MyDependency类的实例 - private readonly MyDependency _dependency; - public IndexModel(){ - // 创建一个MyDependency实例 - // MyDependency是一个依赖项,为IndexModel提供数据 - _dependency = new MyDependency(); - } - public void DoSomething() - { - _dependency.WriteMessage("超级侦探"); - } - } - - //Program.cs - public static void Main(string[] args) - { - // 调用 CreateWebHostBuilder 方法来创建一个 IWebHostBuilder 实例 - var app = CreateWebHostBuilder(args).Build(); - // 在这里实例化 IndexModel 并调用方法进行测试 - var indexModel = new IndexModel(); - indexModel.DoSomething(); - // 运行应用程序 - app.Run(); //控制台输出:调用的数据为超级侦探 - } -~~~ -从上面可知: -- 想要替换 MyDependency的结果,必须修改 IndexModel 类 -- 很难进行单元测试 -- 如果 MyDependency 具有依赖项,则必须由 IndexModel 类对其进行配置 -依赖关系注入通过以下方式解决这些问题: -- 使用接口或基类将依赖关系实现抽象化 -- 在服务容器中注册依赖关系。 ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务通常已在应用的 Program.cs 文件中注册 -- 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放 -~~~js - // 下面是构造函数注入 - // MyDependency.cs - // IMyDependency 接口 - public interface IMyDependency - { - // 定义了一个方法 WriteMessage(string message)用于写入消息 - void WriteMessage(string message); - } - // MyDependency 类实现了 IMyDependency 接口 - // 提供了 WriteMessage 方法的具体实现 - public class MyDependency : IMyDependency - { - public void WriteMessage(string message) - { - Console.WriteLine($"调用的数据为{message}"); - } - } - - // IndexModel.cs - public class IndexModel - { - // 构造_idependency属性,并在构造函数中注入(属性注入) - private readonly IMyDependency _idependency; - // 使用构造函数注入的方式来将 IMyDependency 的具体实现注入到 IndexModel 中 - public IndexModel(IMyDependency dependency){ - // 控制反转,不需要直接new实例化 - _idependency = dependency; - } - public void DoSomething() - { - _idependency.WriteMessage("超级侦探"); - } - } - - // Startup.cs - // 启动类,包含应用程序的配置信息 - public class Startup - { - public void Configure(IApplicationBuilder app) - { - // ...... - } - public void ConfigureServices(IServiceCollection services) - { - // 将 MyDependency 类注册为单例服务 - // 注册 将IMyDependency实现类MyDependency实例化一个,放入容器 - services.AddSingleton(); - // 将 IndexModel 类注册为作用域服务 - services.AddScoped(); - } - } - - // program.cs - public static void Main(string[] args) - { - var app = CreateWebHostBuilder(args).Build(); - // 在 using 语句中创建作用域,以便在作用域内获取服务 - using (var scope = app.Services.CreateScope()) - { - // 获取服务提供者 services - var services = scope.ServiceProvider; - // 从服务提供者中获取 IndexModel 的实例 - var indexModel = services.GetService(); - indexModel.DoSomething(); //控制台输出 调用的数据为超级侦探 - } - app.Run(); - } -~~~ -#### 3.依赖注入容器 -- 专门的类用来负责管理创建所需要的类,并创建它所有可能要用到的依赖,这个类就是依赖注入容器,也可以称之为控制反转容器(IoC容器) -- 可以把依赖注入容器看作一个用于创建对象的工厂,它负责向外提供被请求要创建的对象,当创建这个对象时,如果它又依赖了其他对象或者服务,那么容器会负责在其内部查找需要的依赖,并创建这些依赖,直至所有依赖项都创建完成后,最终返回被请求的对象 -- 容器也负责管理所创建对象的生命周期 - -### 三、ASP.NET Core中的依赖注入 -1. ASP.NET Core框架内部集成了自身的依赖注入容器 -2. 所有被放入依赖注入容器的类型或组件称为服务,添加服务就使用Startup类的ConfigureServices方法 -3. 服务的生命周期有以下三种: - - Singleton:容器会创建并共享服务的单例,且一直存在于应用程序的整个生命周期里 - - TRansient:每次请求,总会创建新实例 - - Scope:在每次请求时会创建服务的新实例,并在这个请求内一直共享这个实例 \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240523\344\276\235\350\265\226\346\263\250\345\205\245.md" "b/\347\231\275\345\251\211\345\251\267/20240523\344\276\235\350\265\226\346\263\250\345\205\245.md" new file mode 100644 index 0000000000000000000000000000000000000000..ff4d554621606b435242bbcaa61e59ae2e1585bf --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240523\344\276\235\350\265\226\346\263\250\345\205\245.md" @@ -0,0 +1,119 @@ +## 路由控制器 +1. 新建文件 Controll → HelloController.cs +2. Controller.cs + using Microsoft.AspNetCore.Mvc; + namespace DemoOne.Controllers{ + public class HelloController: ControllerBase + { + [Route("[Controller]")] + public IActionResult Index(){ + return Ok ("6666"); + } + } + } //路由控制器 +3. Program.cs + var builder = WebApplication.CreateBuilder(args); + builder.Services.AddControllers(); // 添加对控制器的支持 + var app = builder.Build(); + app.MapGet("/",async ctx => { + await ctx.Response.WriteAsync("8888"); + }); + app.MapGet("/leaf",async ctx => { + await ctx.Response.WriteAsync("9999"); + }); + app.MapGet("/ok",()=>"0000"); + app.MapControllers(); // 这将启用控制器路由 + app.Run(); +4. 运行 api.http + GET {{url}}/Hello HTTP/1.1 + +## 在最简单的形式下,转换为在单独的文件中写路径-抽离 +## 在最简形式下,转换为原来传统的控制器的模式-转换 + api传统方式 +1. 定义一个类型 (类型包含函数) + 新建Startup.cs文件 +2. 定义一个函数 + (静态函数 or 实例函数) + 实例完类型才可调用 + namespace DemoOne; + + public class Startup + { + /* + 用于注册中间件 + + + */ + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); + app.UseEndpoints(endpoints=>endpoints.MapControllers()); + } + + /* + 注册服务(一来注入服务)==技术 + + + */ + public void ConfigureServices ( IServiceCollection services) + { + services.AddControllers(); + } + } +3. Program.cs 文件 + using Microsoft.AspNetCore; + namespace DemoOne; //命名空间?? + public class Program + { + public static void Main(string[]args) + { + CreateWebHostbBuilder (args).Build().Run(); + + } + + private static IWebHostBuilder CreateWebHostbBuilder(string[] args) + { + return WebHost.CreateDefaultBuilder(args).UseStartup(); + } + }; +## 依赖注入 +1. 控制反转的其中一种实现:依赖注入-构造函数注入 + using Microsoft.AspNetCore.Identity; + namespace DemoOne; + // 假设在当前类型中,需要用到另外一个类型Users实例 + + public class UserRole + { + private readonly IUsers _iUsers; //只读 + //控制反转的其中一种实现:依赖注入-构造函数注入 + public UserRole(IUsers users) + { + _iUsers = users; + } + public void Run() + { + _iUsers.Run(); + } + } + // 依赖接口 UserRole.cs文件中 private readonly IUsers _iUsers; + //接口不变 不在意修改User.cs or IUsers.cs + //原来依赖具体实现 抽象后只依赖具体函数 +2. using Microsoft.AspNetCore.Mvc; + namespace DemoOne.Controllers{ + public class HelloController: ControllerBase + { /* !!! */ + private readonly IUsers _iUsers; + + public HelloController(IUsers users) + { + _iUsers = users; + } + /* !!! */ + [Route("[Controller]")] + public IActionResult Index(){ + var uu = new UserRole(); + + return Ok ("6666"); + } + } +} \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240524.md" "b/\347\231\275\345\251\211\345\251\267/20240524.md" index bc1507fd62c4d5863771cd74a72a1a07fce0af64..a859c966ceedc5e75b270c82e1298fff092e5b98 100644 --- "a/\347\231\275\345\251\211\345\251\267/20240524.md" +++ "b/\347\231\275\345\251\211\345\251\267/20240524.md" @@ -1,70 +1,2 @@ -1. 入口程序 -~~~c# - using Microsoft.AspNetCore; - // 1. 命名空间声明 - namespace Api - { - // 2. 类声明 - // Program类是应用程序的入口点,应用程序通常从Main方法开始执行 - public class Program - { - public static void Main(string[] args) - { - CreateWebHostBuilder(args).Build().Run(); - // CreateWebHostBuilder(args)方法被调用来创建一个IWebHostBuilder对象 - // Build()方法被调用在IWebHostBuilder对象上,生成一个IWebHost对象 - // Run()方法启动Web主机,使应用程序开始监听Web请求 - } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) - { - return WebHost.CreateDefaultBuilder(args).UseStartup(); - // CreateWebHostBuilder方法用于配置和创建一个Web主机生成器 - // UseStartup()方法指定Startup类作为应用程序的启动类 - } - } - } -~~~ -2. 启动类 -~~~c# - // Startup类是ASP.NET Core应用程序启动时调用的类,用于配置应用程序服务和HTTP请求管道 - public class Startup - { - // 用于添加和注册中间件 - public void Configure(IApplicationBuilder app) - { - app.UseRouting(); //添加路由中间件 - // 配置终结点路由 - app.UseEndpoints(endpoints => { - endpoints.MapControllers(); - // 添加控制器终结点到请求管道中,这使得控制器能够处理HTTP请求 - }); - } - // 注册准备依赖注入的服务 - // ConfigureServices方法用于配置依赖注入容器,添加应用程序所需的服务 - public void ConfigureServices(IServiceCollection services) - { - services.AddControllers(); //添加MVC控制器相关的服务到依赖注入容器中 - } - } -~~~ -3. 控制器 -~~~c# - namespace Api.Controllers; - - [Route("[controller]")] //定义控制器的路由前缀,即/blogs - // BlogsController类继承自ControllerBase,它是一个用于构建API的基类(不包含视图支持) - public class BlogsController : ControllerBase - { - // 处理对/blogs的GET请求 - public IActionResult Index(){ - return Ok("999"); //返回一个包含字符串"999"的200 OK响应 - } - - [Route("{id}")] //定义Single方法的路由模板 - // 处理对/blogs/{id}的GET请求,接受一个整型参数id - public IActionResult Single(int id) - { - return Ok(id); //返回一个包含id值的200 OK响应 - } - } -~~~ \ No newline at end of file +## >?? +## src形式 \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240527.md" "b/\347\231\275\345\251\211\345\251\267/20240527.md" new file mode 100644 index 0000000000000000000000000000000000000000..56807bab088253fc2e79f67d2a5317a0cc13b01e --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240527.md" @@ -0,0 +1,230 @@ +一、路由 +1.概念 + +根据路由配置确定如何处理该请求。路由定义了不同 URL 地址对应的控制器和操作方法 +2.示例 + +[Route("[controller]")] //定义控制器的路由前缀,即/blogs +// BlogsController类继承自ControllerBase,它是一个用于构建API的基类(不包含视图支持) +public class BlogsController : ControllerBase +{ + // 处理对/blogs的GET请求 + public IActionResult Index(){ + return Ok("999"); //返回一个包含字符串"999"的200 OK响应 + } + + [Route("{id}")] //定义Single方法的路由模板 + // 处理对/blogs/{id}的GET请求,接受一个整型参数id + public IActionResult Single(int id) + { + return Ok(id); //返回一个包含id值的200 OK响应 + } +} + +// 上面两个函数可以合并写为以下形式: + [Route("{id?}")] + public IActionResult Index(){ + // 代码块 + } + public IActionResult Single(int id) + { + // 代码块 + } + +3.拓展:关于控制器 + + 控制器是应用程序负责处理用户请求并生成响应的类 + 本身带有多个action方法,而每个action方法对应着一个特定的HTTP请求类型,可以接受参数、调用服务、查询数据库等等 + 通常继承自ControllerBase类(不包含视图)或Controller类 + +二、模型绑定 +1.概念 + + 一旦根据路由确定要调用的操作方法,就会尝试从请求中提取数据,将其绑定到操作方法的参数或模型对象上 + 模型绑定不仅可以处理基本的数据类型,还可以解析复杂的数据 + +2.Action特性 + + [FromQuery]:从HTTP请求的查询字符串中获取参数的值 + [FromForm]:从表单中获取参数的值 + [FromHeader]:从HTTP 请求的头部信息中获取参数值 + [FromBody]:从请求的内容体获取参数值 + [FromServices]:从依赖注入容器中获取参数值 + [FromRoute]:从路由中获取参数值 + [BindRequiredAttribute]:如果没有值绑定到此参数,或绑定不成功,这个特性将添加一个ModelState错误 + +// 这里需要下载包 +using Microsoft.AspNetCore.Mvc.ModelBinding; +namespace Api; +public class BlogDto +{ + [BindRequired] //强调该值必须填写 + public string Title {get;set;}; +} + + [BindNever]:在进行模板绑定时,忽略此参数 + [ApiController]:位于命名空间下方,会尝试自动获取参数值,不再需要为参数指定上述其他特性 + +3.示例 + + // Dto/BlogDto.cs + public class BlogDto + { + public string Title {get;set;} = null!; + public string Author {get;set;} = null!; + public string? Flag {get;set;} + } + // BlogsController.cs + [HttpPost] + public ActionResult Post(BlogDto blogDto) + { + return blogDto; + } + +4.拓展:什么是VO、DTO、DO、PO + +VO、DTO、DO、PO 是常见的命名约定,通常用于表示不同的数据对象或数据传输对象 + + VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来 + DTO(Data Transfer Object):数据传输对象,用于在不同层之间传输数据 + DO(Domain Object):领域对象,从现实世界中抽象出来的有形或无形的业务实体,例如商品、订单、用户等 + PO(Persistent Object):持久化对象,数据需要被保存到持久存储介质(比如数据库、文件系统等)中,PO就是用来表示这些持久化数据的对象 + +三、模型验证 + +是指数据被使用之前的验证过程,它发生在模型绑定之后 +1.数据注解 + +使用Required特性为属性添加需要的数据验证 + + using System.ComponentModel.DataAnnotations; + namespace Api; + public class BlogDto + { + [MinLength(2,ErrorMessage="标题不能少于2个字符")] + public string Title {get;set;} = null!; + [Required(ErrorMessage="作者不能为空")] + public string Author {get;set;} = null!; + public string? Flag {get;set;} + } + + // BlogsController.cs + // 检查对象是否满足指定的条件 + public ActionResult Put(int id,BlogDto blogDto) + { + if (!ModelState.IsValid){ + return BadRequest(ModelState); + }else + { + + return Ok(new { id, blogDto }); + } + } + +2.继承自ValidationAttribute类的自定义验证 + + // Atrribute/NoSpaceAttribute.cs + using System; + using System.ComponentModel.DataAnnotations; + + public class NoSpaceAttribute : ValidationAttribute + { + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (value != null && value.ToString().Contains(" ")) + { + // 返回如果包含空格的错误验证消息 + return new ValidationResult("字符串不能包含空格"); + } + else + { + // 返回成功验证结果 + return ValidationResult.Success; + } + } + } + // 在属性中使用 + [NoSpace] + public string Author {get;set;} = null!; + +3.使用Model实现IValidatableObject接口自定义验证 + + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + namespace Api + { + public class BlogDto : IValidatableObject + { + public string Title { get; set; } = null!; + + public string Author { get; set; } = null!; + public string? Flag { get; set; } + + public IEnumerable Validate (ValidationContext validationContext) + { + if (IsContainSpace(Title)) + { + yield return new ValidationResult("标题不能包含空格", new[] { nameof(Title) }); + } + } + + private bool IsContainSpace(string value) + { + return value?.Contains(" ") ?? false; + } + } + } + +四、执行控制器方法Action +1.概念 + + 一个控制器包括一个或多个Action,而Action是控制器中的一些public类型的函数,它们可以接受参数、执行相关逻辑,最终返回一个结果,该结果作为HTTP响应返回给客户端 + 如果要让一个Action不起作用,在它上方添加[NonAction] + +2.常见的返回结果类型 + +Action根据实际需求,可以接受参数也可以不接受,可以返回任何类型的值 +1.状态码 + + Ok():操作成功200 + BadRequest():错误请求400 + NoContent():操作成功都是不返回任何内容204 + NotFound():资源找不到404 + Unauthorized():未授权401 + +2.包含对象的状态码 + +这一类结果继承自ObjectResult,包括OkObjectResult、CreateResult和NotObjectResult等等 + + [HttpPut("{id}")] + public ActionResult Put(int id,BlogDto blogDto) + { + var res = new ObjectResult(new {id,blogDto}); + return res; + } + +3.重定向结果 + + // 重定向到指定url + return Redirect("http://www.baidu.com/"); + // 重定向到当前应用程序中的另一个url + return LocalRedirect("/blogs/users"); // Location: /blogs/users + // 重定向到指定Action + return RedirectToAction("index"); // Location: /Blogs + // 重定向到指定的路由 + return RedirectToRoute("default", new { controller = "Blogs", action = "Details" }); + +4.内容结果 + + // 返回视图ViewResult、PartialViewResult + // 返回JSON字符串 + return new JsonResult(new { + msg = "This is a JSON result", + data = blogDto + }); + // Content返回一个字符串 + return Content("我是添加数据"); + +此外还可以使用ActionResult类,即可以表示ActionResult对象,也可以表示一个具体类型(由泛型参数T指定) diff --git "a/\347\231\275\345\251\211\345\251\267/20240528.md" "b/\347\231\275\345\251\211\345\251\267/20240528.md" new file mode 100644 index 0000000000000000000000000000000000000000..36950a8039c1148f937acbe8cc3a14de7b66c790 --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240528.md" @@ -0,0 +1,179 @@ +五、过滤器 +1.概念 + +过滤器和中间件相似,能够在某些功能前后执行,通常用于执行日志记录、身份验证、授权、异常处理和结果转换等操作 +2.过滤器类型 + + 授权过滤器(Authorization Filter):最先执行,用于检查用户是否有权访问资源,并在未经授权时拦截请求,实现IAsyncAuthorizationFilter或IAuthorizationFilter接口 + 资源过滤器(Resource Filter):在Authorization后执行,并在其他过滤器之前和之后执行,实现IAsyncResourceFilter或IResourceFilter接口 + 动作过滤器(Action Filter):在执行Action之前或之后执行自定义逻辑,而且在模型绑定后执行,实现IAsyncActionFilter或IActionFilter接口 + 异常过滤器(Exception Filter):用于捕获并处理动作方法中抛出的异常,实现IAsyncExceptionFilter或IExceptionFilter接口 + 结果过滤器(Result Filter):在IActionResult执行的前后执行,能够控制Action的执行结果,比如格式化结果等。需要注意的是,它只有在Action方法成功执行完成后才会运行,实现IAsyncResultFilter或IResultFilter接口 + +3.示例 + + // 对于每次请求都需要设置return结果,这里可以使用Result过滤器格式化结果 + // 1. Dto/ApiResult.cs + public class ApiResult + { + public int Code { get; set; } + public string? Msg { get; set; } + public object Data { get; set; } + } + // 2. Filters/ApiResultFilter.cs 实现接口 + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Filters; + using System.Threading.Tasks; + namespace Api.Filters; + public class ApiResultFilter:IAsyncResultFilter{ + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + // 判断返回结果是否为内容,如果是则给context.Result赋值一个新的实例对象ApiResult + if (context.Result is ObjectResult objectResult) + { + context.Result = new ObjectResult(new ApiResult + { + Code = 1000, + Msg = "请求成功", + Data = objectResult.Value + }); + } + else + { + context.Result = new ObjectResult(new ApiResult { Code = 4000, Msg = "无效请求" }); + } + // 必须记得调用,否则不能执行下一个Action + await next(); + } + } + // 3. Startup.cs 注册服务 + public void ConfigureServices(IServiceCollection services) + { + // 全局过滤 + services.AddControllers(options => { + options.Filters.Add(); + }); + } + +六、配置 +1.概念 + + 采用键值对来表示配置项,并且支持多种形式的配置源,包括文件(支持JSON、XML和INI格式)、命令行参数、环境变量、.NET内存对象等等 + 要访问配置,需要使用ConfigurationBuilder类,位于Microsoft.Extensions.Configuration命名空间下,实现IConfigurationBuilder接口,该接口包括两个重要的方法 + + public interface IConfiguration + { + // Add添加不同形式的配置源 + IConfigurationBuilder Add(IConfigurationSource source); + // Build把配置源生成为程序可访问的配置项 + IConfigurationRoot Build(); + } + +2.访问JSON配置文件 + + // appsetting.json + { + "MySettings": { + "Setting1": "Value1", + "Setting2": "Value2" + } + } + // startup.cs + // IConfiguration 用于读取应用程序的配置 + private readonly IConfiguration _configuration; + public Startup(IConfiguration configuration) + { + _configuration = configuration; + } + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); + app.UseEndpoints(endpoints => { + endpoints.MapControllers(); + + }); + } + public void ConfigureServices(IServiceCollection services) + { + // 输出配置值并打印到控制台 + var setting1 = _configuration["MySettings:Setting1"]; + Console.WriteLine($"Setting1: {setting1}"); + } + +3.访问其他配置源 + + 使用AddXmlFile添加XML文件 + 使用AddIniFile添加Ini文件 + 使用AddInMemoryCollection添加KeyValuePair类型的集合,键和值的类型均为字符串 + AddEnvronmentVariables添加当前系统的所有环境变量 + +七、日志 +1.概念 + + 日志不会为应用程序增加实质性的功能,但是能够让开发人员跟踪程序的运行、调试程序以及记录错误信息 + 日志两种类型: + 系统日志:系统在运行时向外输出的记录信息 + 用户记录日志:开发人员在程序中适当的位置调用与日志功能相关的API输出 + 由以下接口组成:(都位于Microsoft.Extensions.Logging命名空间下 + Ilogger:实际执行记录日志操作的方法 + IloggerProvider:用于创建ILogger对象 + IloggerFactory:通过ILoggerProvider对象创建ILogger对象 + 日志级别: + Trace:级别最低 + Debug:用于记录调试信息 + Information:用于记录应用程序的执行流程信息 + Warning:用于记录应用程序出现的轻微错误或其他不会导致程序停止的警告信息 + Critical:严重级别最高,用于记录引起应用程序崩溃、灾难性故障等信息 + +2.Serilog + +Serilog 是一款广受欢迎的日志库,它提供了强大的日志记录功能 +1.安装 + +dotnet add package Serilog + +2.配置Serilog + + public class Program + { + public static void Main(string[] args) + { + // 设置 Serilog 日志配置 + Log.Logger = new LoggerConfiguration() + .WriteTo.Console() //日志输出到控制台 + .CreateLogger(); //创建并初始化 Log.Logger 静态实例 + CreateWebHostBuilder(args).Build().Run(); + } + public static IWebHostBuilder CreateWebHostBuilder(string[] args) + { + return WebHost.CreateDefaultBuilder(args) + .UseSerilog() // 将 Serilog 集成到 ASP.NET Core + .UseStartup(); + } + } + +3.记录日志 + + namespace Api.Controllers + { + [ApiController] + [Route("[controller]")] + public class LogController : ControllerBase + { + // 声明了一个只读的 _logger 字段,用于记录日志 + private readonly ILogger _logger; + // 构造函数通过依赖注入获取 + public LogController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public IActionResult Index() + { + // 记录一条信息级别的日志,表示访问了首页 + _logger.LogInformation("访问了首页"); + return Ok("Welcome to the homepage"); + } + } + } \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240530.md" "b/\347\231\275\345\251\211\345\251\267/20240530.md" new file mode 100644 index 0000000000000000000000000000000000000000..c6b383b28ded78fa1f8202a2aeadc4096f964ce1 --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240530.md" @@ -0,0 +1,70 @@ + + 入口程序 + + using Microsoft.AspNetCore; + // 1. 命名空间声明 + namespace Api + { + // 2. 类声明 + // Program类是应用程序的入口点,应用程序通常从Main方法开始执行 + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + // CreateWebHostBuilder(args)方法被调用来创建一个IWebHostBuilder对象 + // Build()方法被调用在IWebHostBuilder对象上,生成一个IWebHost对象 + // Run()方法启动Web主机,使应用程序开始监听Web请求 + } + public static IWebHostBuilder CreateWebHostBuilder(string[] args) + { + return WebHost.CreateDefaultBuilder(args).UseStartup(); + // CreateWebHostBuilder方法用于配置和创建一个Web主机生成器 + // UseStartup()方法指定Startup类作为应用程序的启动类 + } + } + } + + 启动类 + + // Startup类是ASP.NET Core应用程序启动时调用的类,用于配置应用程序服务和HTTP请求管道 + public class Startup + { + // 用于添加和注册中间件 + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); //添加路由中间件 + // 配置终结点路由 + app.UseEndpoints(endpoints => { + endpoints.MapControllers(); + // 添加控制器终结点到请求管道中,这使得控制器能够处理HTTP请求 + }); + } + // 注册准备依赖注入的服务 + // ConfigureServices方法用于配置依赖注入容器,添加应用程序所需的服务 + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); //添加MVC控制器相关的服务到依赖注入容器中 + } + } + + 控制器 + + namespace Api.Controllers; + + [Route("[controller]")] //定义控制器的路由前缀,即/blogs + // BlogsController类继承自ControllerBase,它是一个用于构建API的基类(不包含视图支持) + public class BlogsController : ControllerBase + { + // 处理对/blogs的GET请求 + public IActionResult Index(){ + return Ok("999"); //返回一个包含字符串"999"的200 OK响应 + } + + [Route("{id}")] //定义Single方法的路由模板 + // 处理对/blogs/{id}的GET请求,接受一个整型参数id + public IActionResult Single(int id) + { + return Ok(id); //返回一个包含id值的200 OK响应 + } + } \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240531.md" "b/\347\231\275\345\251\211\345\251\267/20240531.md" new file mode 100644 index 0000000000000000000000000000000000000000..761c2a2a7359a5134b084d1aa961a2936df3a3d1 --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240531.md" @@ -0,0 +1 @@ +建设中 \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-1.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..0fcde51100c7a55b4ccba15ca6ab4fa384f4638e Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-1.png" differ diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-2.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..4eff595d8f8132b89a3b3dea435a5a3e46956c34 Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-2.png" differ diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-3.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..c538ed77a8aae47952745099a1be88bf2dd6e3f9 Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\346\212\275\347\246\273-3.png" differ diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-1.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..49feaa6b3ef40e5396f57db484fcb8d3355054b6 Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-1.png" differ diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-2.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..76c8acd4d3f4bff450b0604885a5cbf39356f755 Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-2.png" differ diff --git "a/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-3.png" "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a777b951869123863cad941781a3e414be03074 Binary files /dev/null and "b/\347\231\275\345\251\211\345\251\267/JPG/20240523\350\267\257\347\224\261-3.png" differ