From 7b019bc25e1dd2482a815ef23836fa45cd538ee1 Mon Sep 17 00:00:00 2001 From: Galymzhan Date: Sun, 18 Jun 2023 01:01:14 +0600 Subject: [PATCH 1/4] add swagger --- Startup.cs | 21 ++++++++++++++------- TodoApiDTO.csproj | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Startup.cs b/Startup.cs index bbfbc83d..1cb5ffd9 100644 --- a/Startup.cs +++ b/Startup.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpsPolicy; -using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; using TodoApi.Models; namespace TodoApi @@ -30,6 +24,11 @@ public void ConfigureServices(IServiceCollection services) services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList")); services.AddControllers(); + + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", new OpenApiInfo { Title = "Todo API", Version = "v1" }); + }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -50,6 +49,14 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { endpoints.MapControllers(); }); + + // swagger + app.UseSwagger(); + + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("v1/swagger.json", "Todo API V1"); + }); } } } diff --git a/TodoApiDTO.csproj b/TodoApiDTO.csproj index bba6f6af..6c186056 100644 --- a/TodoApiDTO.csproj +++ b/TodoApiDTO.csproj @@ -12,6 +12,7 @@ + From d4375d4f7f4d94a841e218576f22a464bba73d65 Mon Sep 17 00:00:00 2001 From: Galymzhan Date: Sun, 18 Jun 2023 03:24:34 +0600 Subject: [PATCH 2/4] add MS SQL Server connection and migrations --- {Models => TodoApi.BLL/Dto}/TodoItemDTO.cs | 4 +- TodoApi.BLL/TodoApi.BLL.csproj | 6 +++ .../20230617212119_Initial.Designer.cs | 46 +++++++++++++++++++ .../Migrations/20230617212119_Initial.cs | 31 +++++++++++++ .../Migrations/TodoContextModelSnapshot.cs | 44 ++++++++++++++++++ {Models => TodoApi.DAL/Models}/TodoItem.cs | 6 +-- TodoApi.DAL/ReadMe.txt | 4 ++ TodoApi.DAL/TodoApi.DAL.csproj | 12 +++++ {Models => TodoApi.DAL}/TodoContext.cs | 5 +- TodoApiDTO.sln | 26 ++++++++--- .../Controllers}/TodoItemsController.cs | 6 ++- Program.cs => TodoApiDTO/Program.cs | 0 .../Properties}/launchSettings.json | 0 README.md => TodoApiDTO/README.md | 0 Startup.cs => TodoApiDTO/Startup.cs | 4 +- .../TodoApiDTO.csproj | 6 +++ .../appsettings.Development.json | 0 .../appsettings.json | 3 ++ 18 files changed, 183 insertions(+), 20 deletions(-) rename {Models => TodoApi.BLL/Dto}/TodoItemDTO.cs (72%) create mode 100644 TodoApi.BLL/TodoApi.BLL.csproj create mode 100644 TodoApi.DAL/Migrations/20230617212119_Initial.Designer.cs create mode 100644 TodoApi.DAL/Migrations/20230617212119_Initial.cs create mode 100644 TodoApi.DAL/Migrations/TodoContextModelSnapshot.cs rename {Models => TodoApi.DAL/Models}/TodoItem.cs (76%) create mode 100644 TodoApi.DAL/ReadMe.txt create mode 100644 TodoApi.DAL/TodoApi.DAL.csproj rename {Models => TodoApi.DAL}/TodoContext.cs (84%) rename {Controllers => TodoApiDTO/Controllers}/TodoItemsController.cs (97%) rename Program.cs => TodoApiDTO/Program.cs (100%) rename {Properties => TodoApiDTO/Properties}/launchSettings.json (100%) rename README.md => TodoApiDTO/README.md (100%) rename Startup.cs => TodoApiDTO/Startup.cs (93%) rename TodoApiDTO.csproj => TodoApiDTO/TodoApiDTO.csproj (77%) rename appsettings.Development.json => TodoApiDTO/appsettings.Development.json (100%) rename appsettings.json => TodoApiDTO/appsettings.json (53%) diff --git a/Models/TodoItemDTO.cs b/TodoApi.BLL/Dto/TodoItemDTO.cs similarity index 72% rename from Models/TodoItemDTO.cs rename to TodoApi.BLL/Dto/TodoItemDTO.cs index e66a500a..7f0131a2 100644 --- a/Models/TodoItemDTO.cs +++ b/TodoApi.BLL/Dto/TodoItemDTO.cs @@ -1,11 +1,9 @@ -namespace TodoApi.Models +namespace TodoApi.BLL.Dto { - #region snippet public class TodoItemDTO { public long Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } } - #endregion } diff --git a/TodoApi.BLL/TodoApi.BLL.csproj b/TodoApi.BLL/TodoApi.BLL.csproj new file mode 100644 index 00000000..9737f8e3 --- /dev/null +++ b/TodoApi.BLL/TodoApi.BLL.csproj @@ -0,0 +1,6 @@ + + + netcoreapp3.1 + false + + diff --git a/TodoApi.DAL/Migrations/20230617212119_Initial.Designer.cs b/TodoApi.DAL/Migrations/20230617212119_Initial.Designer.cs new file mode 100644 index 00000000..c0234ec2 --- /dev/null +++ b/TodoApi.DAL/Migrations/20230617212119_Initial.Designer.cs @@ -0,0 +1,46 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TodoApi.DAL; + +namespace TodoApi.DAL.Migrations +{ + [DbContext(typeof(TodoContext))] + [Migration("20230617212119_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("TodoApi.DAL.Models.TodoItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IsComplete") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Secret") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TodoItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/TodoApi.DAL/Migrations/20230617212119_Initial.cs b/TodoApi.DAL/Migrations/20230617212119_Initial.cs new file mode 100644 index 00000000..a6613cf1 --- /dev/null +++ b/TodoApi.DAL/Migrations/20230617212119_Initial.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace TodoApi.DAL.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "TodoItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(nullable: true), + IsComplete = table.Column(nullable: false), + Secret = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_TodoItems", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TodoItems"); + } + } +} diff --git a/TodoApi.DAL/Migrations/TodoContextModelSnapshot.cs b/TodoApi.DAL/Migrations/TodoContextModelSnapshot.cs new file mode 100644 index 00000000..5a66a7c2 --- /dev/null +++ b/TodoApi.DAL/Migrations/TodoContextModelSnapshot.cs @@ -0,0 +1,44 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TodoApi.DAL; + +namespace TodoApi.DAL.Migrations +{ + [DbContext(typeof(TodoContext))] + partial class TodoContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("TodoApi.DAL.Models.TodoItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IsComplete") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Secret") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TodoItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Models/TodoItem.cs b/TodoApi.DAL/Models/TodoItem.cs similarity index 76% rename from Models/TodoItem.cs rename to TodoApi.DAL/Models/TodoItem.cs index 1f6e5465..255729e0 100644 --- a/Models/TodoItem.cs +++ b/TodoApi.DAL/Models/TodoItem.cs @@ -1,6 +1,5 @@ -namespace TodoApi.Models +namespace TodoApi.DAL.Models { - #region snippet public class TodoItem { public long Id { get; set; } @@ -8,5 +7,4 @@ public class TodoItem public bool IsComplete { get; set; } public string Secret { get; set; } } - #endregion -} \ No newline at end of file +} diff --git a/TodoApi.DAL/ReadMe.txt b/TodoApi.DAL/ReadMe.txt new file mode 100644 index 00000000..73094590 --- /dev/null +++ b/TodoApi.DAL/ReadMe.txt @@ -0,0 +1,4 @@ +Пример создания миграции +dotnet ef migrations add Initial --startup-project ../TodoApiDTO +Обновление базы данных +dotnet ef database update --startup-project ../TodoApiDTO \ No newline at end of file diff --git a/TodoApi.DAL/TodoApi.DAL.csproj b/TodoApi.DAL/TodoApi.DAL.csproj new file mode 100644 index 00000000..63de6e0f --- /dev/null +++ b/TodoApi.DAL/TodoApi.DAL.csproj @@ -0,0 +1,12 @@ + + + netcoreapp3.1 + false + + + + + + + + diff --git a/Models/TodoContext.cs b/TodoApi.DAL/TodoContext.cs similarity index 84% rename from Models/TodoContext.cs rename to TodoApi.DAL/TodoContext.cs index 6e59e363..e5fcfd7b 100644 --- a/Models/TodoContext.cs +++ b/TodoApi.DAL/TodoContext.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; +using TodoApi.DAL.Models; -namespace TodoApi.Models +namespace TodoApi.DAL { public class TodoContext : DbContext { @@ -11,4 +12,4 @@ public TodoContext(DbContextOptions options) public DbSet TodoItems { get; set; } } -} \ No newline at end of file +} diff --git a/TodoApiDTO.sln b/TodoApiDTO.sln index e49c182b..7c980187 100644 --- a/TodoApiDTO.sln +++ b/TodoApiDTO.sln @@ -1,9 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30002.166 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32421.90 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApiDTO", "TodoApiDTO.csproj", "{623124F9-F5BA-42DD-BC26-A1720774229C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApiDTO", "TodoApiDTO\TodoApiDTO.csproj", "{178C50E1-26FF-4169-9FF9-28293CC81965}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApi.DAL", "TodoApi.DAL\TodoApi.DAL.csproj", "{3EC653C1-BD41-4AD1-9C60-2DF0761971D5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApi.BLL", "TodoApi.BLL\TodoApi.BLL.csproj", "{A17F0E7B-BBB2-4016-98FC-08ED58DCD955}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +15,18 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {623124F9-F5BA-42DD-BC26-A1720774229C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {623124F9-F5BA-42DD-BC26-A1720774229C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {623124F9-F5BA-42DD-BC26-A1720774229C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {623124F9-F5BA-42DD-BC26-A1720774229C}.Release|Any CPU.Build.0 = Release|Any CPU + {178C50E1-26FF-4169-9FF9-28293CC81965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {178C50E1-26FF-4169-9FF9-28293CC81965}.Debug|Any CPU.Build.0 = Debug|Any CPU + {178C50E1-26FF-4169-9FF9-28293CC81965}.Release|Any CPU.ActiveCfg = Release|Any CPU + {178C50E1-26FF-4169-9FF9-28293CC81965}.Release|Any CPU.Build.0 = Release|Any CPU + {3EC653C1-BD41-4AD1-9C60-2DF0761971D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3EC653C1-BD41-4AD1-9C60-2DF0761971D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3EC653C1-BD41-4AD1-9C60-2DF0761971D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3EC653C1-BD41-4AD1-9C60-2DF0761971D5}.Release|Any CPU.Build.0 = Release|Any CPU + {A17F0E7B-BBB2-4016-98FC-08ED58DCD955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A17F0E7B-BBB2-4016-98FC-08ED58DCD955}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A17F0E7B-BBB2-4016-98FC-08ED58DCD955}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A17F0E7B-BBB2-4016-98FC-08ED58DCD955}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Controllers/TodoItemsController.cs b/TodoApiDTO/Controllers/TodoItemsController.cs similarity index 97% rename from Controllers/TodoItemsController.cs rename to TodoApiDTO/Controllers/TodoItemsController.cs index 0ef138e7..16babd29 100644 --- a/Controllers/TodoItemsController.cs +++ b/TodoApiDTO/Controllers/TodoItemsController.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using TodoApi.Models; +using TodoApi.BLL.Dto; +using TodoApi.DAL; +using TodoApi.DAL.Models; namespace TodoApi.Controllers { @@ -111,6 +113,6 @@ private static TodoItemDTO ItemToDTO(TodoItem todoItem) => Id = todoItem.Id, Name = todoItem.Name, IsComplete = todoItem.IsComplete - }; + }; } } diff --git a/Program.cs b/TodoApiDTO/Program.cs similarity index 100% rename from Program.cs rename to TodoApiDTO/Program.cs diff --git a/Properties/launchSettings.json b/TodoApiDTO/Properties/launchSettings.json similarity index 100% rename from Properties/launchSettings.json rename to TodoApiDTO/Properties/launchSettings.json diff --git a/README.md b/TodoApiDTO/README.md similarity index 100% rename from README.md rename to TodoApiDTO/README.md diff --git a/Startup.cs b/TodoApiDTO/Startup.cs similarity index 93% rename from Startup.cs rename to TodoApiDTO/Startup.cs index 1cb5ffd9..5da20dd6 100644 --- a/Startup.cs +++ b/TodoApiDTO/Startup.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; -using TodoApi.Models; +using TodoApi.DAL; namespace TodoApi { @@ -22,7 +22,7 @@ public Startup(IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { services.AddDbContext(opt => - opt.UseInMemoryDatabase("TodoList")); + opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); services.AddSwaggerGen(c => diff --git a/TodoApiDTO.csproj b/TodoApiDTO/TodoApiDTO.csproj similarity index 77% rename from TodoApiDTO.csproj rename to TodoApiDTO/TodoApiDTO.csproj index 6c186056..5f11c796 100644 --- a/TodoApiDTO.csproj +++ b/TodoApiDTO/TodoApiDTO.csproj @@ -2,6 +2,7 @@ netcoreapp3.1 + false @@ -15,5 +16,10 @@ + + + + + diff --git a/appsettings.Development.json b/TodoApiDTO/appsettings.Development.json similarity index 100% rename from appsettings.Development.json rename to TodoApiDTO/appsettings.Development.json diff --git a/appsettings.json b/TodoApiDTO/appsettings.json similarity index 53% rename from appsettings.json rename to TodoApiDTO/appsettings.json index d9d9a9bf..497e6c06 100644 --- a/appsettings.json +++ b/TodoApiDTO/appsettings.json @@ -6,5 +6,8 @@ "Microsoft.Hosting.Lifetime": "Information" } }, + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=TodoList;User=sa;Password=StrongPassword123;MultipleActiveResultSets=true;" + }, "AllowedHosts": "*" } From 2ce186b3afd0f10398b00cf54f436f5d26c94827 Mon Sep 17 00:00:00 2001 From: Galymzhan Date: Sun, 18 Jun 2023 03:54:29 +0600 Subject: [PATCH 3/4] add error logging to file through Serilog --- TodoApiDTO/Controllers/TodoItemsController.cs | 8 +++- .../Middleware/ErrorLoggingMiddleware.cs | 39 +++++++++++++++++++ TodoApiDTO/Startup.cs | 16 +++++++- TodoApiDTO/TodoApiDTO.csproj | 4 +- TodoApiDTO/logs/myapp-errors.txt | 22 +++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 TodoApiDTO/Middleware/ErrorLoggingMiddleware.cs create mode 100644 TodoApiDTO/logs/myapp-errors.txt diff --git a/TodoApiDTO/Controllers/TodoItemsController.cs b/TodoApiDTO/Controllers/TodoItemsController.cs index 16babd29..909e48b0 100644 --- a/TodoApiDTO/Controllers/TodoItemsController.cs +++ b/TodoApiDTO/Controllers/TodoItemsController.cs @@ -1,5 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Serilog; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -14,10 +16,13 @@ namespace TodoApi.Controllers public class TodoItemsController : ControllerBase { private readonly TodoContext _context; + private readonly ILogger _logger; - public TodoItemsController(TodoContext context) + + public TodoItemsController(TodoContext context, ILogger logger) { _context = context; + _logger = logger; } [HttpGet] @@ -35,6 +40,7 @@ public async Task> GetTodoItem(long id) if (todoItem == null) { + _logger.LogError($"Not Found TodoItem With Id {id}"); return NotFound(); } diff --git a/TodoApiDTO/Middleware/ErrorLoggingMiddleware.cs b/TodoApiDTO/Middleware/ErrorLoggingMiddleware.cs new file mode 100644 index 00000000..9702613e --- /dev/null +++ b/TodoApiDTO/Middleware/ErrorLoggingMiddleware.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Serilog; +using System; +using System.Threading.Tasks; + +namespace TodoApiDTO.Middleware +{ + public class ErrorLoggingMiddleware + { + private readonly RequestDelegate _next; + + public ErrorLoggingMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + try + { + await _next(context); + } + catch (Exception ex) + { + Log.Error(ex, "An unhandled exception occurred during the request."); + throw; // Rethrow the exception to let the global error handling middleware handle it + } + } + } + + public static class ErrorLoggingMiddlewareExtensions + { + public static IApplicationBuilder UseErrorLogging(this IApplicationBuilder app) + { + return app.UseMiddleware(); + } + } +} diff --git a/TodoApiDTO/Startup.cs b/TodoApiDTO/Startup.cs index 5da20dd6..6e576cd7 100644 --- a/TodoApiDTO/Startup.cs +++ b/TodoApiDTO/Startup.cs @@ -5,7 +5,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; +using Serilog; using TodoApi.DAL; +using TodoApiDTO.Middleware; namespace TodoApi { @@ -21,10 +23,15 @@ public Startup(IConfiguration configuration) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + services.AddLogging(loggingBuilder => + { + loggingBuilder.AddSerilog(dispose: true); // Add Serilog logger + }); + services.AddDbContext(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); - + services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Todo API", Version = "v1" }); @@ -34,6 +41,13 @@ public void ConfigureServices(IServiceCollection services) // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + // Configure Serilog + Log.Logger = new LoggerConfiguration() + .WriteTo.File("logs/myapp-errors.txt") + .CreateLogger(); + + app.UseErrorLogging(); // Add the custom middleware for error logging + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); diff --git a/TodoApiDTO/TodoApiDTO.csproj b/TodoApiDTO/TodoApiDTO.csproj index 5f11c796..94795f7c 100644 --- a/TodoApiDTO/TodoApiDTO.csproj +++ b/TodoApiDTO/TodoApiDTO.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -13,6 +13,8 @@ + + diff --git a/TodoApiDTO/logs/myapp-errors.txt b/TodoApiDTO/logs/myapp-errors.txt new file mode 100644 index 00000000..0cbba298 --- /dev/null +++ b/TodoApiDTO/logs/myapp-errors.txt @@ -0,0 +1,22 @@ +2023-06-18 03:52:16.739 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 03:52:16.773 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 03:52:17.123 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 03:52:17.553 +06:00 [INF] Executed DbCommand (45ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 03:52:19.871 +06:00 [ERR] Not Found TodoItem With Id 5 +2023-06-18 03:52:21.254 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 03:52:21.260 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 4482.8974ms +2023-06-18 03:52:21.262 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 03:53:09.588 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 03:53:09.589 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 03:53:09.617 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 03:53:09.625 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 03:53:11.148 +06:00 [ERR] Not Found TodoItem With Id 768 +2023-06-18 03:53:11.148 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 03:53:11.149 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 1559.8201ms +2023-06-18 03:53:11.149 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' From 7ca50b2a86dae1e8d76b20c288a40126c9fef13e Mon Sep 17 00:00:00 2001 From: Galymzhan Date: Sun, 18 Jun 2023 04:50:06 +0600 Subject: [PATCH 4/4] did refactoring by deviding to buissness and data layers --- TodoApi.BLL/Implementation/Repository.cs | 51 +++ .../Implementation/TodoItemsService.cs | 103 ++++++ TodoApi.BLL/Interfaces/IRepository.cs | 15 + TodoApi.BLL/Interfaces/ITodoItemsService.cs | 15 + TodoApi.BLL/TodoApi.BLL.csproj | 6 + TodoApiDTO/Controllers/TodoItemsController.cs | 83 ++--- TodoApiDTO/Program.cs | 6 - TodoApiDTO/Startup.cs | 6 + TodoApiDTO/logs/myapp-errors.txt | 298 ++++++++++++++++++ 9 files changed, 519 insertions(+), 64 deletions(-) create mode 100644 TodoApi.BLL/Implementation/Repository.cs create mode 100644 TodoApi.BLL/Implementation/TodoItemsService.cs create mode 100644 TodoApi.BLL/Interfaces/IRepository.cs create mode 100644 TodoApi.BLL/Interfaces/ITodoItemsService.cs diff --git a/TodoApi.BLL/Implementation/Repository.cs b/TodoApi.BLL/Implementation/Repository.cs new file mode 100644 index 00000000..455d1528 --- /dev/null +++ b/TodoApi.BLL/Implementation/Repository.cs @@ -0,0 +1,51 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Threading.Tasks; +using TodoApi.BLL.Interfaces; +using TodoApi.DAL; + +namespace TodoApi.BLL.Implementation +{ + public class Repository : IRepository where T : class + { + private readonly DbContext _dbContext; + + public Repository(TodoContext dbContext) + { + _dbContext = dbContext; + } + + public T GetById(long id) + { + return _dbContext.Set().Find(id); + } + + public async Task GetByIdAsync(long id) + { + return await _dbContext.Set().FindAsync(id); + } + + public async Task> GetAllAsync() + { + return await _dbContext.Set().ToListAsync(); + } + + public async Task AddAsync(T entity) + { + await _dbContext.Set().AddAsync(entity); + await _dbContext.SaveChangesAsync(); + } + + public async Task UpdateAsync(T entity) + { + _dbContext.Set().Update(entity); + await _dbContext.SaveChangesAsync(); + } + + public async Task DeleteAsync(T entity) + { + _dbContext.Set().Remove(entity); + await _dbContext.SaveChangesAsync(); + } + } +} diff --git a/TodoApi.BLL/Implementation/TodoItemsService.cs b/TodoApi.BLL/Implementation/TodoItemsService.cs new file mode 100644 index 00000000..59fc9bcf --- /dev/null +++ b/TodoApi.BLL/Implementation/TodoItemsService.cs @@ -0,0 +1,103 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using TodoApi.BLL.Dto; +using TodoApi.BLL.Interfaces; +using TodoApi.DAL.Models; + +namespace TodoApi.BLL.Implementation +{ + public class TodoItemsService : ITodoItemsService + { + private readonly IRepository _repository; + + public TodoItemsService(IRepository repository) + { + _repository = repository; + } + + + public async Task> GetTodoItemsAsync() + { + var items = await _repository.GetAllAsync(); + return items.Select(i => ItemToDTO(i)); + } + + public async Task UpdateTodoItemAsync(long id, TodoItemDTO todoItemDTO) + { + if (id != todoItemDTO.Id) + { + throw new Exception("id != todoItemDTO.Id"); + } + + var todoItem = await _repository.GetByIdAsync(id); + if (todoItem == null) + { + return false; + } + + todoItem.Name = todoItemDTO.Name; + todoItem.IsComplete = todoItemDTO.IsComplete; + + try + { + await _repository.UpdateAsync(todoItem); + } + catch (DbUpdateConcurrencyException) when (_repository.GetById(id) == null) + { + return false; + } + + return true; + } + + private static TodoItemDTO ItemToDTO(TodoItem todoItem) => + new TodoItemDTO + { + Id = todoItem.Id, + Name = todoItem.Name, + IsComplete = todoItem.IsComplete + }; + + public async Task GetTodoItemAsync(long id) + { + var todoItem = await _repository.GetByIdAsync(id); + + if (todoItem == null) + { + return null; + } + + return ItemToDTO(todoItem); + } + + public async Task CreateTodoItemAsync(TodoItemDTO todoItemDTO) + { + var todoItem = new TodoItem + { + IsComplete = todoItemDTO.IsComplete, + Name = todoItemDTO.Name + }; + + await _repository.AddAsync(todoItem); + + return ItemToDTO(todoItem); + } + + public async Task DeleteTodoItemAsync(long id) + { + var todoItem = await _repository.GetByIdAsync(id); + + if (todoItem == null) + { + return false; + } + + await _repository.DeleteAsync(todoItem); + + return true; + } + } +} diff --git a/TodoApi.BLL/Interfaces/IRepository.cs b/TodoApi.BLL/Interfaces/IRepository.cs new file mode 100644 index 00000000..a3daf65f --- /dev/null +++ b/TodoApi.BLL/Interfaces/IRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace TodoApi.BLL.Interfaces +{ + public interface IRepository + { + T GetById(long id); + Task GetByIdAsync(long id); + Task> GetAllAsync(); + Task AddAsync(T entity); + Task UpdateAsync(T entity); + Task DeleteAsync(T entity); + } +} diff --git a/TodoApi.BLL/Interfaces/ITodoItemsService.cs b/TodoApi.BLL/Interfaces/ITodoItemsService.cs new file mode 100644 index 00000000..f9de3722 --- /dev/null +++ b/TodoApi.BLL/Interfaces/ITodoItemsService.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using TodoApi.BLL.Dto; + +namespace TodoApi.BLL.Interfaces +{ + public interface ITodoItemsService + { + Task> GetTodoItemsAsync(); + Task GetTodoItemAsync(long id); + Task UpdateTodoItemAsync(long id, TodoItemDTO todoItemDTO); + Task CreateTodoItemAsync(TodoItemDTO todoItemDTO); + Task DeleteTodoItemAsync(long id); + } +} diff --git a/TodoApi.BLL/TodoApi.BLL.csproj b/TodoApi.BLL/TodoApi.BLL.csproj index 9737f8e3..ecec13e6 100644 --- a/TodoApi.BLL/TodoApi.BLL.csproj +++ b/TodoApi.BLL/TodoApi.BLL.csproj @@ -3,4 +3,10 @@ netcoreapp3.1 false + + + + + + diff --git a/TodoApiDTO/Controllers/TodoItemsController.cs b/TodoApiDTO/Controllers/TodoItemsController.cs index 909e48b0..d4e3d44e 100644 --- a/TodoApiDTO/Controllers/TodoItemsController.cs +++ b/TodoApiDTO/Controllers/TodoItemsController.cs @@ -1,13 +1,11 @@ using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Serilog; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TodoApi.BLL.Dto; +using TodoApi.BLL.Interfaces; using TodoApi.DAL; -using TodoApi.DAL.Models; namespace TodoApi.Controllers { @@ -17,108 +15,77 @@ public class TodoItemsController : ControllerBase { private readonly TodoContext _context; private readonly ILogger _logger; + private readonly ITodoItemsService _todoItemsService; - - public TodoItemsController(TodoContext context, ILogger logger) + public TodoItemsController( + TodoContext context, + ILogger logger, + ITodoItemsService todoItemsService) { _context = context; _logger = logger; + _todoItemsService = todoItemsService; } [HttpGet] public async Task>> GetTodoItems() { - return await _context.TodoItems - .Select(x => ItemToDTO(x)) - .ToListAsync(); + var items = await _todoItemsService.GetTodoItemsAsync(); + return items.ToList(); } [HttpGet("{id}")] public async Task> GetTodoItem(long id) { - var todoItem = await _context.TodoItems.FindAsync(id); + var todoItemDto = await _todoItemsService.GetTodoItemAsync(id); - if (todoItem == null) + if (todoItemDto == null) { - _logger.LogError($"Not Found TodoItem With Id {id}"); return NotFound(); } - return ItemToDTO(todoItem); + return todoItemDto; } [HttpPut("{id}")] public async Task UpdateTodoItem(long id, TodoItemDTO todoItemDTO) { - if (id != todoItemDTO.Id) - { - return BadRequest(); - } + var updateResult = await _todoItemsService.UpdateTodoItemAsync(id, todoItemDTO); - var todoItem = await _context.TodoItems.FindAsync(id); - if (todoItem == null) + if (updateResult) { - return NotFound(); + return NoContent(); } - - todoItem.Name = todoItemDTO.Name; - todoItem.IsComplete = todoItemDTO.IsComplete; - - try - { - await _context.SaveChangesAsync(); - } - catch (DbUpdateConcurrencyException) when (!TodoItemExists(id)) + else { return NotFound(); } - - return NoContent(); } [HttpPost] public async Task> CreateTodoItem(TodoItemDTO todoItemDTO) { - var todoItem = new TodoItem - { - IsComplete = todoItemDTO.IsComplete, - Name = todoItemDTO.Name - }; - - _context.TodoItems.Add(todoItem); - await _context.SaveChangesAsync(); + var todoItemDto = await _todoItemsService.CreateTodoItemAsync(todoItemDTO); return CreatedAtAction( nameof(GetTodoItem), - new { id = todoItem.Id }, - ItemToDTO(todoItem)); + new { id = todoItemDto.Id }, + todoItemDto); } [HttpDelete("{id}")] public async Task DeleteTodoItem(long id) { - var todoItem = await _context.TodoItems.FindAsync(id); + var deleteResult = await _todoItemsService.DeleteTodoItemAsync(id); - if (todoItem == null) + if (deleteResult) + { + return NoContent(); + } + else { return NotFound(); } - - _context.TodoItems.Remove(todoItem); - await _context.SaveChangesAsync(); - - return NoContent(); } - - private bool TodoItemExists(long id) => - _context.TodoItems.Any(e => e.Id == id); - - private static TodoItemDTO ItemToDTO(TodoItem todoItem) => - new TodoItemDTO - { - Id = todoItem.Id, - Name = todoItem.Name, - IsComplete = todoItem.IsComplete - }; } } diff --git a/TodoApiDTO/Program.cs b/TodoApiDTO/Program.cs index b27ac16a..4fe9a571 100644 --- a/TodoApiDTO/Program.cs +++ b/TodoApiDTO/Program.cs @@ -1,11 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; namespace TodoApi { diff --git a/TodoApiDTO/Startup.cs b/TodoApiDTO/Startup.cs index 6e576cd7..ddee4646 100644 --- a/TodoApiDTO/Startup.cs +++ b/TodoApiDTO/Startup.cs @@ -6,6 +6,8 @@ using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using Serilog; +using TodoApi.BLL.Implementation; +using TodoApi.BLL.Interfaces; using TodoApi.DAL; using TodoApiDTO.Middleware; @@ -30,6 +32,10 @@ public void ConfigureServices(IServiceCollection services) services.AddDbContext(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); + + services.AddScoped(typeof(IRepository<>), typeof(Repository<>)); + services.AddScoped(); + services.AddControllers(); services.AddSwaggerGen(c => diff --git a/TodoApiDTO/logs/myapp-errors.txt b/TodoApiDTO/logs/myapp-errors.txt index 0cbba298..32a6c4e9 100644 --- a/TodoApiDTO/logs/myapp-errors.txt +++ b/TodoApiDTO/logs/myapp-errors.txt @@ -20,3 +20,301 @@ WHERE [t].[Id] = @__p_0 2023-06-18 03:53:11.148 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. 2023-06-18 03:53:11.149 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 1559.8201ms 2023-06-18 03:53:11.149 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:10:50.016 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:10:50.046 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:10:50.443 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:10:50.893 +06:00 [INF] Executed DbCommand (26ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:10:50.954 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:10:50.963 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 912.5531ms +2023-06-18 04:10:50.964 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:16:19.934 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:16:19.962 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:18:58.086 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:18:58.116 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:18:59.785 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:19:00.134 +06:00 [INF] Executed DbCommand (25ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:19:00.194 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:19:00.203 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 2082.4108ms +2023-06-18 04:19:00.203 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:23:17.000 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:23:17.030 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:23:17.653 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:23:18.261 +06:00 [INF] Executed DbCommand (25ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:23:18.319 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:23:18.326 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 1292.3416ms +2023-06-18 04:23:18.327 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:23:23.802 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:23.815 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:23:23.855 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:23:23.953 +06:00 [INF] Executed DbCommand (30ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:23:23.955 +06:00 [INF] Executing ObjectResult, writing value of type 'TodoApi.BLL.Dto.TodoItemDTO'. +2023-06-18 04:23:23.956 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 140.5836ms +2023-06-18 04:23:23.956 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:26.907 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:26.907 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:23:26.915 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:23:26.922 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:23:26.923 +06:00 [INF] Executing ObjectResult, writing value of type 'TodoApi.BLL.Dto.TodoItemDTO'. +2023-06-18 04:23:26.924 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 15.9346ms +2023-06-18 04:23:26.924 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:29.551 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:29.551 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:23:29.553 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:23:29.559 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:23:29.563 +06:00 [INF] Executing ObjectResult, writing value of type 'TodoApi.BLL.Dto.TodoItemDTO'. +2023-06-18 04:23:29.564 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 12.1527ms +2023-06-18 04:23:29.564 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:30.938 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:23:30.939 +06:00 [INF] Route matched with {action = "GetTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] GetTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:23:30.940 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:23:30.946 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:23:33.279 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:23:33.281 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO) in 2342.2093ms +2023-06-18 04:23:33.281 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItem (TodoApiDTO)' +2023-06-18 04:35:44.975 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:35:45.009 +06:00 [INF] Route matched with {action = "UpdateTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] UpdateTodoItem(Int64, TodoApi.BLL.Dto.TodoItemDTO) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:35:45.186 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO) in 172.8564ms +2023-06-18 04:35:45.187 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:35:45.262 +06:00 [ERR] An unhandled exception has occurred while executing the request. +System.Exception: id != todoItemDTO.Id + at TodoApi.BLL.Implementation.TodoItemsService.UpdateTodoItemAsync(Int64 id, TodoItemDTO todoItemDTO) in C:\Work\VelvetechTestTask\TodoApi.BLL\Implementation\TodoItemsService.cs:line 45 + at TodoApi.Controllers.TodoItemsController.UpdateTodoItem(Int64 id, TodoItemDTO todoItemDTO) in C:\Work\VelvetechTestTask\TodoApiDTO\Controllers\TodoItemsController.cs:line 55 + at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() +--- End of stack trace from previous location where exception was thrown --- + at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) + at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) + at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) + at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) +2023-06-18 04:35:53.098 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:35:53.099 +06:00 [INF] Route matched with {action = "UpdateTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] UpdateTodoItem(Int64, TodoApi.BLL.Dto.TodoItemDTO) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:35:53.145 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO) in 46.3616ms +2023-06-18 04:35:53.146 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:35:53.151 +06:00 [ERR] An unhandled exception has occurred while executing the request. +System.Exception: id != todoItemDTO.Id + at TodoApi.BLL.Implementation.TodoItemsService.UpdateTodoItemAsync(Int64 id, TodoItemDTO todoItemDTO) in C:\Work\VelvetechTestTask\TodoApi.BLL\Implementation\TodoItemsService.cs:line 45 + at TodoApi.Controllers.TodoItemsController.UpdateTodoItem(Int64 id, TodoItemDTO todoItemDTO) in C:\Work\VelvetechTestTask\TodoApiDTO\Controllers\TodoItemsController.cs:line 55 + at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() +--- End of stack trace from previous location where exception was thrown --- + at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) + at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) + at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) + at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) + at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) +2023-06-18 04:36:07.210 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:36:07.211 +06:00 [INF] Route matched with {action = "UpdateTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] UpdateTodoItem(Int64, TodoApi.BLL.Dto.TodoItemDTO) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:36:07.470 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:36:07.906 +06:00 [INF] Executed DbCommand (48ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:36:08.031 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[@p3='?' (DbType = Int64), @p0='?' (DbType = Boolean), @p1='?' (Size = 4000), @p2='?' (Size = 4000)], CommandType='"Text"', CommandTimeout='30'] +SET NOCOUNT ON; +UPDATE [TodoItems] SET [IsComplete] = @p0, [Name] = @p1, [Secret] = @p2 +WHERE [Id] = @p3; +SELECT @@ROWCOUNT; +2023-06-18 04:36:08.055 +06:00 [INF] Executing HttpStatusCodeResult, setting HTTP status code 204 +2023-06-18 04:36:08.056 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO) in 845.032ms +2023-06-18 04:36:08.056 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.UpdateTodoItem (TodoApiDTO)' +2023-06-18 04:36:12.979 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:36:12.986 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:36:13.008 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:36:13.018 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:36:13.024 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:36:13.027 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 40.731ms +2023-06-18 04:36:13.027 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:39:56.687 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.CreateTodoItem (TodoApiDTO)' +2023-06-18 04:39:56.722 +06:00 [INF] Route matched with {action = "CreateTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[TodoApi.BLL.Dto.TodoItemDTO]] CreateTodoItem(TodoApi.BLL.Dto.TodoItemDTO) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:39:57.071 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:39:57.461 +06:00 [INF] Executed DbCommand (45ms) [Parameters=[@p0='?' (DbType = Boolean), @p1='?' (Size = 4000), @p2='?' (Size = 4000)], CommandType='"Text"', CommandTimeout='30'] +SET NOCOUNT ON; +INSERT INTO [TodoItems] ([IsComplete], [Name], [Secret]) +VALUES (@p0, @p1, @p2); +SELECT [Id] +FROM [TodoItems] +WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity(); +2023-06-18 04:39:57.518 +06:00 [INF] Executing ObjectResult, writing value of type 'TodoApi.BLL.Dto.TodoItemDTO'. +2023-06-18 04:39:57.544 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.CreateTodoItem (TodoApiDTO) in 817.0716ms +2023-06-18 04:39:57.544 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.CreateTodoItem (TodoApiDTO)' +2023-06-18 04:40:03.008 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:40:03.015 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:40:03.046 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:40:03.147 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:40:03.158 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:40:03.159 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 143.1231ms +2023-06-18 04:40:03.159 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:43:12.710 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:43:12.738 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:13.078 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:13.422 +06:00 [INF] Executed DbCommand (25ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:43:13.481 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:43:13.489 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 746.0809ms +2023-06-18 04:43:13.489 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:43:19.658 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:19.673 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:19.709 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:19.802 +06:00 [INF] Executed DbCommand (27ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:19.872 +06:00 [INF] Executed DbCommand (6ms) [Parameters=[@p0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SET NOCOUNT ON; +DELETE FROM [TodoItems] +WHERE [Id] = @p0; +SELECT @@ROWCOUNT; +2023-06-18 04:43:19.897 +06:00 [INF] Executing HttpStatusCodeResult, setting HTTP status code 204 +2023-06-18 04:43:19.897 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 223.7761ms +2023-06-18 04:43:19.897 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:23.635 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:43:23.636 +06:00 [INF] Route matched with {action = "GetTodoItems", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[TodoApi.BLL.Dto.TodoItemDTO]]] GetTodoItems() on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:23.642 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:23.647 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +2023-06-18 04:43:23.648 +06:00 [INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.List`1[[TodoApi.BLL.Dto.TodoItemDTO, TodoApi.BLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'. +2023-06-18 04:43:23.649 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO) in 12.7899ms +2023-06-18 04:43:23.649 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.GetTodoItems (TodoApiDTO)' +2023-06-18 04:43:27.102 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:27.102 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:27.104 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:27.110 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:27.112 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:27.114 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 10.8156ms +2023-06-18 04:43:27.114 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:29.234 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:29.234 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:29.235 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:29.240 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:29.241 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:29.242 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 7.5309ms +2023-06-18 04:43:29.242 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:29.774 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:29.775 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:29.777 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:29.785 +06:00 [INF] Executed DbCommand (4ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:29.787 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:29.788 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 12.6571ms +2023-06-18 04:43:29.788 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:30.440 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:30.440 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:30.442 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:30.447 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:30.448 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:30.449 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 8.7765ms +2023-06-18 04:43:30.449 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:30.928 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:30.928 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:30.934 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:30.938 +06:00 [INF] Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:30.939 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:30.940 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 11.4382ms +2023-06-18 04:43:30.940 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.126 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.126 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.127 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.130 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.131 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.131 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 4.7759ms +2023-06-18 04:43:31.131 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.287 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.287 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.289 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.293 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.294 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.294 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 6.7979ms +2023-06-18 04:43:31.294 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.421 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.421 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.422 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.425 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.425 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.426 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 4.1364ms +2023-06-18 04:43:31.426 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.566 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.566 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.567 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.569 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.570 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.570 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 4.1379ms +2023-06-18 04:43:31.570 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.701 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.702 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.703 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.707 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.707 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.708 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 6.1665ms +2023-06-18 04:43:31.708 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.805 +06:00 [INF] Executing endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)' +2023-06-18 04:43:31.805 +06:00 [INF] Route matched with {action = "DeleteTodoItem", controller = "TodoItems"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] DeleteTodoItem(Int64) on controller TodoApi.Controllers.TodoItemsController (TodoApiDTO). +2023-06-18 04:43:31.805 +06:00 [INF] Entity Framework Core 3.1.0 initialized 'TodoContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None +2023-06-18 04:43:31.808 +06:00 [INF] Executed DbCommand (2ms) [Parameters=[@__p_0='?' (DbType = Int64)], CommandType='"Text"', CommandTimeout='30'] +SELECT TOP(1) [t].[Id], [t].[IsComplete], [t].[Name], [t].[Secret] +FROM [TodoItems] AS [t] +WHERE [t].[Id] = @__p_0 +2023-06-18 04:43:31.808 +06:00 [INF] Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ProblemDetails'. +2023-06-18 04:43:31.809 +06:00 [INF] Executed action TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO) in 3.9561ms +2023-06-18 04:43:31.809 +06:00 [INF] Executed endpoint 'TodoApi.Controllers.TodoItemsController.DeleteTodoItem (TodoApiDTO)'