diff --git "a/\350\256\270\345\205\260\350\216\271/05230\345\233\276\344\271\246\347\256\241\347\220\206\347\263\273\347\273\237.md" "b/\350\256\270\345\205\260\350\216\271/05230\345\233\276\344\271\246\347\256\241\347\220\206\347\263\273\347\273\237.md" new file mode 100644 index 0000000000000000000000000000000000000000..c5df9838c6d0da63065c4f5edc0c1e4fa05c056b --- /dev/null +++ "b/\350\256\270\345\205\260\350\216\271/05230\345\233\276\344\271\246\347\256\241\347\220\206\347\263\273\347\273\237.md" @@ -0,0 +1,147 @@ +**创建项目** + +打开集成终端,写入以下代码 + +- 创建项目 + dotnet new webapi -o/-n 项目名称 + cd 项目名称 +- 启动项目 + dotnet run/dotnet watch --project .\项目名称\ + +**打开Program.cs** +```cs +// 定义一个名为TodoA的命名空间 +namespace TodoA +{ + // 定义一个公共静态类,用于应用程序的入口点 + public static class Program + { + // 主函数,应用程序的入口点,接收命令行参数 + public static void Main(string[] args) + { + // 创建一个HostBuilder实例,用于配置和构建应用程序 + IHostBuilder hostBuilder = CreateHostBuilder(args); + + // 使用Build方法构建和启动应用程序 + hostBuilder.Build().Run(); + } + + // 创建HostBuilder的静态方法,用于配置WebHost的默认设置 + public static IHostBuilder CreateHostBuilder(string[] args) + { + // 使用Host类的CreateDefaultBuilder方法创建一个新的Builder实例,传入命令行参数 + return Host.CreateDefaultBuilder(args); + + // 添加WebHost的默认配置,即使用Startup类作为应用程序的启动点 + .ConfigureWebHostDefaults(builder => + { + builder.UseStartup(); + }); + } + } +} +``` + +**在同层创建一个Startup.cs文件,写入以下代码** +```cs +// 定义一个名为TodoA的命名空间 +namespace TodoA + // 定义一个公共类,用于应用程序的启动和配置 + public class Startup + { + // 配置服务容器的方法,用于注册依赖注入的服务 + public void ConfigureServices(IServiceCollection services) + { + // 注册控制器服务 + services.AddControllers(); + } + + // 配置中间件管道的方法,用于设置HTTP请求处理的流程 + public void Configure(IApplicationBuilder app) + { + // 使用Routing中间件,用于路由匹配 + app.UseRouting(); + + // 使用Endpoints中间件,用于管理终结点 + app.UseEndpoints(endPoints => + { + // 将控制器终结点映射到应用程序中 + endPoints.MapControllers(); + }); + } + } +``` +**在Controller文件夹中添加BooksController.cs文件,写图书的信息,实现crud** +```cs +using Microsoft.AspNetCore.Mvc; // 引入ASP.NET Core MVC的命名空间,用于控制器和动作方法的创建 + +namespace TodoA; // 定义命名空间,用于组织代码 + +[ApiController] // 标记该类为API控制器,启用一些API控制器的特性 +[Route("/api/[controller]")] // 定义控制器的路由模板,[controller]将替换为控制器名称 + +public class BooksController : ControllerBase // 定义一个公共类BooksController,继承自ControllerBase +{ + // 查询操作,通过HTTP GET请求获取特定ID的书籍信息 + [HttpGet("{id}")] // 使用HTTP GET方法,并定义路径参数{id} + public IActionResult Get(int id, BooksDto booksDto) // 定义Get方法,接收一个整数id和一个BooksDto对象 + { + return Ok(new { id, booksDto }); // 返回包含id和booksDto的Ok结果 + } + + // 增加操作,通过HTTP POST请求添加新的书籍信息 + [HttpPost] // 使用HTTP POST方法 + public IActionResult Post(BooksDto booksDto) // 定义Post方法,接收一个BooksDto对象 + { + return Ok(new { booksDto }); // 返回包含booksDto的Ok结果 + } + + // 修改操作,通过HTTP PUT请求更新特定ID的书籍信息 + [HttpPut("{id}")] // 使用HTTP PUT方法,并定义路径参数{id} + public IActionResult Put(int id, BooksDto booksDto) // 定义Put方法,接收一个整数id和一个BooksDto对象 + { + return Ok(new { id, booksDto }); // 返回包含id和booksDto的Ok结果 + } + + // 删除操作,通过HTTP DELETE请求删除特定ID的书籍信息 + [HttpDelete("{id}")] // 使用HTTP DELETE方法,并定义路径参数{id} + public IActionResult Delete(int id, BooksDto booksDto) // 定义Delete方法,接收一个整数id和一个BooksDto对象 + { + return Ok(); // 返回一个简单的Ok结果,表示操作成功 + } +}; + +``` +**在同项目中添加一个api.http文件,用于测试增删改查是否成功** +```api.http + +@url=http://localhost:5184 // 定义一个变量url,值为本地服务器地址和端口 + +### // 分隔符,用于区分不同的HTTP请求 +GET {{url}}/api/books/2 HTTP/1.1 // 发起一个GET请求,获取ID为2的书籍信息 + +### // 分隔符 +POST {{url}}/api/books HTTP/1.1 // 发起一个POST请求,创建新的书籍信息 +Content-Type: application/json // 指定请求的内容类型为JSON + +{ // 请求体,包含要创建的书籍信息 + "bName":"着地即可拉伸建档立卡", // 书籍名称 + "bWriter":"dddd", // 作者 + "bStock":2 // 库存量 +} + +### // 分隔符 +PUT {{url}}/api/books/99 HTTP/1.1 // 发起一个PUT请求,更新ID为99的书籍信息 +Content-Type: application/json // 指定请求的内容类型为JSON + +{ // 请求体,包含要更新的书籍信息 + "bName":"十万火急来放哨", // 更新后的书籍名称 + "bWriter":"鹿鹿", // 更新后的作者 + "bStock":1 // 更新后的库存量 +} + +### // 分隔符 +DELETE {{url}}/api/books/1 HTTP/1.1 // 发起一个DELETE请求,删除ID为1的书籍信息 + +``` + diff --git "a/\350\256\270\345\205\260\350\216\271/0527Dto.md" "b/\350\256\270\345\205\260\350\216\271/0527Dto.md" new file mode 100644 index 0000000000000000000000000000000000000000..e74ba2f0baf7e038876709f60dd43e5fcd902f1a --- /dev/null +++ "b/\350\256\270\345\205\260\350\216\271/0527Dto.md" @@ -0,0 +1,138 @@ +## WebAPI DTO 可以用于以下场景: + +1. **数据传输:** 在应用程序的不同层之间传输数据时,可以使用 WebAPI DTO 来封装数据。 +2. **数据验证:** 在传输数据之前,可以对数据进行验证,确保数据的有效性和安全性。 +3. **数据序列化和反序列化:** 在传输数据时,需要对数据进行序列化,在接收数据时,需要对数据进行反序列化。 +4. **数据过滤和分页:** 在传输数据时,需要对数据进行过滤和分页,避免传输不必要的数据和过多的数据。 +5. **数据排序:** 在传输数据时,需要对数据进行排序,以便能够按照特定的顺序传输数据。 +6. **数据压缩:** 在传输数据时,需要对数据进行压缩,以减少网络传输的数据量。 + +### 优点 + +使用 WebAPI DTO 有以下优点: + +1. **数据完整性:** 使用 WebAPI DTO 可以确保数据的完整性,避免漏传或重复传输数据。 +2. **数据格式:** 使用 WebAPI DTO 可以确保数据的格式正确,避免数据格式不匹配。 +3. **数据验证:** 使用 WebAPI DTO 可以对数据进行验证,确保数据的有效性和安全性。 +4. **数据序列化和反序列化:** 使用 WebAPI DTO 可以对数据进行序列化和反序列化,以便在网络传输中能够正确传输数据。 +5. **数据过滤和分页:** 使用 WebAPI DTO 可以对数据进行过滤和分页,避免传输不必要的数据和过多的数据。 +6. **数据排序:** 使用 WebAPI DTO 可以对数据进行排序,以便能够按照特定的顺序传输数据。 +7. **数据压缩:** 使用 WebAPI DTO 可以对数据进行压缩,以减少网络传输的数据量。 + +### 示例代码 + +### DTO 类 +```cs + public class UserDto + { + public int Id { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public DateTime Birthday { get; set; } + } +``` + +### WebAPI 控制器 +```cs + [Route("api/[controller]")] + [ApiController] + public class UsersController : ControllerBase + { + private readonly List _users = new List + { + new User { Id = 1, Name = "John Doe", Email = "john.doe@example.com", Birthday = new DateTime(1980, 1, 1) }, + new User { Id = 2, Name = "Jane Doe", Email = "jane.doe@example.com", Birthday = new DateTime(1990, 1, 1) } + }; + + [HttpGet] + public ActionResult> GetUsers() + { + var users = _users.Select(u => new UserDto + { + Id = u.Id, + Name = u.Name, + Email = u.Email, + Birthday = u.Birthday + }); + + return Ok(users); + } + + [HttpGet("{id}")] + public ActionResult GetUser(int id) + { + var user = _users.FirstOrDefault(u => u.Id == id); + + if (user == null) + { + return NotFound(); + } + + return new UserDto + { + Id = user.Id, + Name = user.Name, + Email = user.Email, + Birthday = user.Birthday + }; + } + + [HttpPost] + public ActionResult PostUser(UserDto userDto) + { + if (userDto == null) + { + return BadRequest(); + } + + var user = new User + { + Id = _users.Max(u => u.Id) + 1, + Name = userDto.Name, + Email = userDto.Email, + Birthday = userDto.Birthday + }; + + _users.Add(user); + + return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user); + } + + [HttpPut("{id}")] + public IActionResult PutUser(int id, UserDto userDto) + { + if (userDto == null || userDto.Id != id) + { + return BadRequest(); + } + + var user = _users.FirstOrDefault(u => u.Id == id); + + if (user == null) + { + return NotFound(); + } + + user.Name = userDto.Name; + user.Email = userDto.Email; + user.Birthday = userDto.Birthday; + + return NoContent(); + } + + [HttpDelete("{id}")] + public IActionResult DeleteUser(int id) + { + var user = _users.FirstOrDefault(u => u.Id == id); + + if (user == null) + { + return NotFound(); + } + + _users.Remove(user); + + return NoContent(); + } + } +``` \ No newline at end of file diff --git "a/\350\256\270\345\205\260\350\216\271/0528\350\267\257\347\224\261.md" "b/\350\256\270\345\205\260\350\216\271/0528\350\267\257\347\224\261.md" new file mode 100644 index 0000000000000000000000000000000000000000..e9a97cdba3fe90818c655ce997d6c2ce396f71d5 --- /dev/null +++ "b/\350\256\270\345\205\260\350\216\271/0528\350\267\257\347\224\261.md" @@ -0,0 +1,221 @@ +```cs + // 在WebApiConfig.cs文件中,定义Web API路由配置 + public static class WebApiConfig + { + // 注册Web API路由 + public static void Register(HttpConfiguration config) + { + // 使用AttributeRoutes,它会自动识别并处理所有使用[Route]注解的方法 + config.MapHttpAttributeRoutes(); + + // 定义一个通用的API路由,参数可选 + // name: 路由名称 + // routeTemplate: 路由模板,"{controller}/{id}" 表示控制器名和操作方法参数 + // defaults: 当请求没有提供id时的默认值 + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } + + // 在Controllers目录下的一个控制器,例如UsersController.cs + // 使用RoutePrefix定义控制器的路由前缀 + [RoutePrefix("api/users")] // 所有操作方法的路由前缀为 "api/users" + public class UsersController : ApiController + { + // 用户列表 + private List _users = new List(); + + // GET请求,获取所有用户 + [HttpGet] // HTTP GET方法 + [Route("")] // 路由模板,表示没有id参数 + public IHttpActionResult GetUsers() // IHttpActionResult用于返回HTTP响应 + { + return Ok(_users); // 返回用户列表 + } + + // GET请求,获取指定ID的用户 + [HttpGet] // HTTP GET方法 + [Route("{id}")] // 路由模板,包含一个可选参数id + public IHttpActionResult GetUser(int id) // 参数id类型为int + { + var user = _users.FirstOrDefault(u => u.Id == id); // 查找匹配的用户 + + if (user == null) + { + return NotFound(); // 未找到用户时返回404错误 + } + + return Ok(user); // 返回用户对象 + } + + // POST请求,创建新的用户 + [HttpPost] // HTTP POST方法 + [Route("")] // 路由模板,表示没有id参数 + public IHttpActionResult PostUser(User user) // 参数user类型为User + { + // ...(这里可以添加用户验证和数据库操作) + _users.Add(user); // 添加新用户到列表 + + // 返回创建成功消息,使用CreatedAtRoute方法 + // routeName: "DefaultApi",表示使用全局默认路由 + // values: { id: user.Id },返回新用户的ID + return CreatedAtRoute("DefaultApi", new { id = user.Id }, user); + } + + // PUT请求,更新指定ID的用户 + [HttpPut] // HTTP PUT方法 + [Route("{id}")] // 路由模板,包含一个参数id + public IHttpActionResult PutUser(int id, User user) + { + if (user == null || user.Id != id) + { + return BadRequest(); // 参数无效或ID不匹配时返回400错误 + } + + var existingUser = _users.FirstOrDefault(u => u.Id == id); + + if (existingUser == null) + { + return NotFound(); // 未找到用户时返回404错误 + } + + // 更新用户信息 + // ...(这里可以添加数据库操作) + + return StatusCode(HttpStatusCode.NoContent); // 更新成功,返回204状态码 + } + + // DELETE请求,删除指定ID的用户 + [HttpDelete] // HTTP DELETE方法 + [Route("{id}")] + public IHttpActionResult DeleteUser(int id) + { + var user = _users.FirstOrDefault(u => u.Id == id); + + if (user == null) + { + return NotFound(); // 未找到用户时返回404错误 + } + + _users.Remove(user); // 从列表中删除用户 + + return StatusCode(HttpStatusCode.NoContent); // 删除成功,返回204状态码 + } + } +``` + +### 1\. 安装 Serilog 和相关包 + +首先,你需要在项目中安装 Serilog 及其相关的 sink 包。可以通过 NuGet 包管理器控制台或 Visual Studio 的 NuGet 包管理器来安装这些包。 + + Install-Package Serilog.AspNetCore + Install-Package Serilog.Sinks.Console + + +### 2\. 配置 Serilog + +在 `Program.cs` 中配置 Serilog。 +```cs + using System; + using System.IO; + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.Hosting; + using Serilog; // 引入 Serilog 命名空间 + + namespace WebApiSerilogExample + { + public class Program + { + public static void Main(string[] args) + { + // 创建配置,从 appsettings.json 读取配置 + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + + // 配置 Serilog,读取 appsettings.json 中的 Serilog 配置 + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .CreateLogger(); + + try + { + Log.Information("Starting up the application"); // 记录启动信息 + CreateHostBuilder(args).Build().Run(); + } + catch (Exception ex) + { + Log.Fatal(ex, "Application start-up failed"); // 记录启动失败信息 + } + finally + { + Log.CloseAndFlush(); // 确保所有日志都被写入 + } + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .UseSerilog() // 使用 Serilog 作为日志记录器 + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } + } +``` + +### 3\. 在 `appsettings.json` 中配置 Serilog +```json + { + "Serilog": { + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "Console" + }, + { + "Name": "File", + "Args": { + "path": "logs/log.txt", + "rollingInterval": "Day" + } + } + ] + } + } +``` + +### 4\. 在控制器中使用 Serilog + +在 `ValuesController.cs` 中使用 Serilog 记录日志。 +```cs + using Microsoft.AspNetCore.Mvc; + using Serilog; // 引入 Serilog 命名空间 + + namespace WebApiSerilogExample.Controllers + { + [ApiController] + [Route("[controller]")] + public class ValuesController : ControllerBase + { + private readonly ILogger _logger; + + public ValuesController(ILogger logger) + { + _logger = logger; // 注入 Serilog 的 ILogger + } + + [HttpGet] + public ActionResult Get() + { + _logger.LogInformation("Received a GET request"); // 记录信息日志 + return "Hello, Serilog!"; + } + } + } +``` \ No newline at end of file diff --git "a/\350\256\270\345\205\260\350\216\271/0531\344\270\252\346\200\247\345\214\226\344\273\223\345\202\250\346\216\245\345\217\243.md" "b/\350\256\270\345\205\260\350\216\271/0531\344\270\252\346\200\247\345\214\226\344\273\223\345\202\250\346\216\245\345\217\243.md" new file mode 100644 index 0000000000000000000000000000000000000000..a279b3b4349241db07efeaa9dd929558a13f114b --- /dev/null +++ "b/\350\256\270\345\205\260\350\216\271/0531\344\270\252\346\200\247\345\214\226\344\273\223\345\202\250\346\216\245\345\217\243.md" @@ -0,0 +1 @@ +接着完成图书管理系统~ \ No newline at end of file