├── .gitignore ├── Readme.md ├── ch_01_hello ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_01_hello.csproj ├── ch_01_hello.http └── ch_01_hello.sln ├── ch_02_routing ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── bin │ └── Debug │ │ └── net8.0 │ │ ├── Microsoft.AspNetCore.OpenApi.dll │ │ ├── Microsoft.OpenApi.dll │ │ ├── Swashbuckle.AspNetCore.Swagger.dll │ │ ├── Swashbuckle.AspNetCore.SwaggerGen.dll │ │ ├── Swashbuckle.AspNetCore.SwaggerUI.dll │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ ├── ch_02_routing.deps.json │ │ ├── ch_02_routing.dll │ │ ├── ch_02_routing.exe │ │ ├── ch_02_routing.pdb │ │ └── ch_02_routing.runtimeconfig.json ├── ch_02_routing.csproj ├── ch_02_routing.http ├── ch_02_routing.sln └── obj │ ├── Debug │ └── net8.0 │ │ ├── .NETCoreApp,Version=v8.0.AssemblyAttributes.cs │ │ ├── apphost.exe │ │ ├── ch_02_ro.C9494480.Up2Date │ │ ├── ch_02_routing.AssemblyInfo.cs │ │ ├── ch_02_routing.AssemblyInfoInputs.cache │ │ ├── ch_02_routing.GeneratedMSBuildEditorConfig.editorconfig │ │ ├── ch_02_routing.GlobalUsings.g.cs │ │ ├── ch_02_routing.MvcApplicationPartsAssemblyInfo.cache │ │ ├── ch_02_routing.MvcApplicationPartsAssemblyInfo.cs │ │ ├── ch_02_routing.assets.cache │ │ ├── ch_02_routing.csproj.AssemblyReference.cache │ │ ├── ch_02_routing.csproj.CoreCompileInputs.cache │ │ ├── ch_02_routing.csproj.FileListAbsolute.txt │ │ ├── ch_02_routing.dll │ │ ├── ch_02_routing.genruntimeconfig.cache │ │ ├── ch_02_routing.pdb │ │ ├── ch_02_routing.sourcelink.json │ │ ├── ref │ │ └── ch_02_routing.dll │ │ ├── refint │ │ └── ch_02_routing.dll │ │ ├── staticwebassets.build.json │ │ └── staticwebassets │ │ ├── msbuild.build.ch_02_routing.props │ │ ├── msbuild.buildMultiTargeting.ch_02_routing.props │ │ └── msbuild.buildTransitive.ch_02_routing.props │ ├── ch_02_routing.csproj.nuget.dgspec.json │ ├── ch_02_routing.csproj.nuget.g.props │ ├── ch_02_routing.csproj.nuget.g.targets │ ├── project.assets.json │ └── project.nuget.cache ├── ch_03_route_parameters ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_03_route_parameters.csproj ├── ch_03_route_parameters.http └── ch_03_route_parameters.sln ├── ch_04_results └── BookApi │ ├── .gitignore │ ├── BookApi.csproj │ ├── BookApi.http │ ├── BookApi.sln │ ├── Models │ └── ErrorModel.wsd │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── ch_05_errors ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_05_errors.csproj ├── ch_05_errors.http └── ch_05_errors.sln ├── ch_06_cors ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_06_cors.csproj ├── ch_06_cors.http └── ch_06_cors.sln ├── ch_07_swagger ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_07_swagger.csproj ├── ch_07_swagger.http └── ch_07_swagger.sln ├── ch_08_validation ├── .gitignore ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_08_validation.csproj ├── ch_08_validation.http └── ch_08_validation.sln ├── ch_09_di ├── .gitignore ├── Models │ └── Model.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_09_di.csproj ├── ch_09_di.http └── ch_09_di.sln ├── ch_10_di_and_interface ├── .gitignore ├── Models │ └── Model.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── ch_10_di_and_interface.csproj ├── ch_10_di_and_interface.http └── ch_10_di_and_interface.sln ├── ch_11_dal ├── Migrations │ ├── 20241120075446_start.Designer.cs │ ├── 20241120075446_start.cs │ ├── 20241120080341_seed-data.Designer.cs │ ├── 20241120080341_seed-data.cs │ └── RepositoryContextModelSnapshot.cs ├── Models │ └── Model.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ └── RepositoryContext.cs ├── appsettings.Development.json ├── appsettings.json ├── ch_11_dal.csproj ├── ch_11_dal.http ├── ch_11_dal.sln └── database.db ├── ch_12_repo_in_use ├── .gitignore ├── Abstracts │ └── IBookService.cs ├── Migrations │ ├── 20241120094804_start.Designer.cs │ ├── 20241120094804_start.cs │ └── RepositoryContextModelSnapshot.cs ├── Models │ └── Model.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ ├── BookRepository.cs │ └── RepositoryContext.cs ├── Services │ ├── BookService.cs │ ├── BookServiceV2.cs │ └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json ├── ch_12_repo_in_use.csproj ├── ch_12_repo_in_use.http ├── ch_12_repo_in_use.sln └── database.db ├── ch_13_automapper ├── .gitignore ├── Abstracts │ └── IBookService.cs ├── BookApi.csproj ├── BookApi.http ├── BookApi.sln ├── Configuration │ ├── ConfigurationExtensions.cs │ └── MappingProfile.cs ├── Entities │ ├── Book.cs │ ├── DTOs │ │ ├── BookDto.cs │ │ ├── BookDtoForInsertion.cs │ │ └── BookDtoForUpdate.cs │ └── Exceptions │ │ ├── BookNotFoundException.cs │ │ ├── ErrorDetails.cs │ │ └── NotFoundException.cs ├── Models │ └── Model.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ ├── BookRepository.cs │ └── RepositoryContext.cs ├── Services │ ├── BookService.cs │ ├── BookServiceV2.cs │ └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json └── database.db ├── ch_14_relations ├── .gitignore ├── Abstracts │ └── IBookService.cs ├── BookApi.csproj ├── BookApi.http ├── BookApi.sln ├── Configuration │ ├── ConfigurationExtensions.cs │ └── MappingProfile.cs ├── Entities │ ├── Book.cs │ ├── Category.cs │ ├── DTOs │ │ ├── BookDto.cs │ │ ├── BookDtoBase.cs │ │ ├── BookDtoForInsertion.cs │ │ └── BookDtoForUpdate.cs │ └── Exceptions │ │ ├── BookNotFoundException.cs │ │ ├── ErrorDetails.cs │ │ └── NotFoundException.cs ├── Migrations │ └── RepositoryContextModelSnapshot.cs ├── Models │ ├── Model.wsd │ └── Model_completed.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ ├── BookRepository.cs │ ├── CategoryRepository.cs │ ├── RepositoryBase.cs │ └── RepositoryContext.cs ├── Services │ ├── AuthorService.cs │ ├── BookService.cs │ ├── BookServiceV2.cs │ └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json └── database.db ├── ch_15_auth ├── .gitignore ├── Abstracts │ ├── IAuthService.cs │ └── IBookService.cs ├── BookApi.csproj ├── BookApi.http ├── BookApi.sln ├── Configuration │ ├── ConfigurationExtensions.cs │ └── MappingProfile.cs ├── Entities │ ├── Book.cs │ ├── Category.cs │ ├── DTOs │ │ ├── BookDto.cs │ │ ├── BookDtoBase.cs │ │ ├── BookDtoForInsertion.cs │ │ ├── BookDtoForUpdate.cs │ │ └── UserForRegistrationDto.cs │ ├── Exceptions │ │ ├── BookNotFoundException.cs │ │ ├── ErrorDetails.cs │ │ └── NotFoundException.cs │ └── User.cs ├── Models │ ├── Model_completed.wsd │ └── Model_start.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ ├── BookRepository.cs │ ├── CategoryRepository.cs │ ├── RepositoryBase.cs │ └── RepositoryContext.cs ├── Services │ ├── AuthenticationManager.cs │ ├── AuthorService.cs │ ├── BookService.cs │ ├── BookServiceV2.cs │ └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json └── database.db ├── ch_16_jwt ├── .gitignore ├── Abstracts │ ├── IAuthService.cs │ └── IBookService.cs ├── BookApi.csproj ├── BookApi.http ├── BookApi.sln ├── Configuration │ ├── ConfigurationExtensions.cs │ └── MappingProfile.cs ├── Entities │ ├── Book.cs │ ├── Category.cs │ ├── DTOs │ │ ├── BookDto.cs │ │ ├── BookDtoBase.cs │ │ ├── BookDtoForInsertion.cs │ │ ├── BookDtoForUpdate.cs │ │ ├── UserForAuthenticationDto.cs │ │ └── UserForRegistrationDto.cs │ ├── Exceptions │ │ ├── BookNotFoundException.cs │ │ ├── ErrorDetails.cs │ │ └── NotFoundException.cs │ └── User.cs ├── Models │ ├── Model_completed.wsd │ └── Model_start.wsd ├── Program.cs ├── Properties │ └── launchSettings.json ├── Repositories │ ├── BookRepository.cs │ ├── CategoryRepository.cs │ ├── RepositoryBase.cs │ └── RepositoryContext.cs ├── Services │ ├── AuthenticationManager.cs │ ├── AuthorService.cs │ ├── BookService.cs │ ├── BookServiceV2.cs │ └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json └── database.db └── ch_17_refresh_token ├── .gitignore ├── Abstracts ├── IAuthService.cs └── IBookService.cs ├── BookApi.csproj ├── BookApi.http ├── BookApi.sln ├── Configuration ├── ConfigurationExtensions.cs └── MappingProfile.cs ├── Entities ├── Book.cs ├── Category.cs ├── DTOs │ ├── BookDto.cs │ ├── BookDtoBase.cs │ ├── BookDtoForInsertion.cs │ ├── BookDtoForUpdate.cs │ ├── TokenDto.cs │ ├── UserForAuthenticationDto.cs │ └── UserForRegistrationDto.cs ├── Exceptions │ ├── BookNotFoundException.cs │ ├── ErrorDetails.cs │ └── NotFoundException.cs └── User.cs ├── Models ├── Model_completed.wsd ├── Model_start.wsd └── get_api_books.wsd ├── Program.cs ├── Properties └── launchSettings.json ├── Repositories ├── BookRepository.cs ├── CategoryRepository.cs ├── RepositoryBase.cs └── RepositoryContext.cs ├── Services ├── AuthenticationManager.cs ├── AuthorService.cs ├── BookService.cs ├── BookServiceV2.cs └── BookServiceV3.cs ├── appsettings.Development.json ├── appsettings.json └── database.db /ch_01_hello/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | builder.Services.AddEndpointsApiExplorer(); 4 | builder.Services.AddSwaggerGen(); 5 | 6 | var app = builder.Build(); 7 | 8 | if (app.Environment.IsDevelopment()) 9 | { 10 | app.UseSwagger(); 11 | app.UseSwaggerUI(); 12 | } 13 | 14 | string message = "Hello world."; 15 | 16 | app.MapGet("/hello", () => 17 | { 18 | return new Response(message); 19 | }) 20 | .WithName("hello") 21 | .WithOpenApi(); 22 | 23 | app.UseHttpsRedirection(); 24 | 25 | app.Run(); 26 | 27 | class Response 28 | { 29 | public Response(string msg) 30 | { 31 | Message = msg; 32 | } 33 | public String? Message { get; set; } 34 | public DateTime? Date => DateTime.Now; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /ch_01_hello/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:24272", 8 | "sslPort": 44390 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5117", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7179;http://localhost:5117", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_01_hello/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_01_hello/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_01_hello/ch_01_hello.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_01_hello/ch_01_hello.http: -------------------------------------------------------------------------------- 1 | @ch_01_hello_HostAddress = http://localhost:5117 2 | 3 | GET {{ch_01_hello_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_01_hello/ch_01_hello.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_01_hello", "ch_01_hello.csproj", "{6C8BB0BF-3EF9-4E19-9D9C-E8983EBC244D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {6C8BB0BF-3EF9-4E19-9D9C-E8983EBC244D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {6C8BB0BF-3EF9-4E19-9D9C-E8983EBC244D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {6C8BB0BF-3EF9-4E19-9D9C-E8983EBC244D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {6C8BB0BF-3EF9-4E19-9D9C-E8983EBC244D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {76C9DC0E-87A0-478E-BB85-A7D1062374D1} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_02_routing/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | builder.Services.AddEndpointsApiExplorer(); 4 | builder.Services.AddSwaggerGen(); 5 | 6 | var app = builder.Build(); 7 | 8 | if (app.Environment.IsDevelopment()) 9 | { 10 | app.UseSwagger(); 11 | app.UseSwaggerUI(); 12 | } 13 | 14 | app.UseHttpsRedirection(); 15 | 16 | var variableLambda = () => "[Variable] Hello World."; 17 | 18 | app.MapGet("/hello", () => "Hello World."); // inline 19 | app.MapPost("/hello", variableLambda); // lambda variable 20 | app.MapPut("/hello", Hello); // local function 21 | app.MapDelete("/hello", new HelloHandler().Hello); // instance member 22 | 23 | 24 | String Hello() 25 | { 26 | return "[Local Function] Hello World."; 27 | } 28 | 29 | 30 | app.Run(); 31 | 32 | class HelloHandler 33 | { 34 | public String? Hello() 35 | { 36 | return "[Instance member] Hello World"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch_02_routing/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:4973", 8 | "sslPort": 44335 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5149", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7251;http://localhost:5149", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_02_routing/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_02_routing/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/Microsoft.AspNetCore.OpenApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/Microsoft.AspNetCore.OpenApi.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/Microsoft.OpenApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/Microsoft.OpenApi.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.Swagger.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.Swagger.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/ch_02_routing.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/ch_02_routing.dll -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/ch_02_routing.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/ch_02_routing.exe -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/ch_02_routing.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/bin/Debug/net8.0/ch_02_routing.pdb -------------------------------------------------------------------------------- /ch_02_routing/bin/Debug/net8.0/ch_02_routing.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net8.0", 4 | "frameworks": [ 5 | { 6 | "name": "Microsoft.NETCore.App", 7 | "version": "8.0.0" 8 | }, 9 | { 10 | "name": "Microsoft.AspNetCore.App", 11 | "version": "8.0.0" 12 | } 13 | ], 14 | "configProperties": { 15 | "System.GC.Server": true, 16 | "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ch_02_routing/ch_02_routing.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_02_routing/ch_02_routing.http: -------------------------------------------------------------------------------- 1 | @ch_02_routing_HostAddress = http://localhost:5149 2 | 3 | GET {{ch_02_routing_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_02_routing/ch_02_routing.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_02_routing", "ch_02_routing.csproj", "{CA22D084-EA04-432E-9B79-A04A76E3F562}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CA22D084-EA04-432E-9B79-A04A76E3F562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CA22D084-EA04-432E-9B79-A04A76E3F562}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CA22D084-EA04-432E-9B79-A04A76E3F562}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {CA22D084-EA04-432E-9B79-A04A76E3F562}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {67AB444A-6220-498A-BA3A-E42D5F82558E} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] 5 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/apphost.exe -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_ro.C9494480.Up2Date: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_ro.C9494480.Up2Date -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | using System; 11 | using System.Reflection; 12 | 13 | [assembly: System.Reflection.AssemblyCompanyAttribute("ch_02_routing")] 14 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 15 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 16 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0dea758a2b13177583b882c8c23543ce7d45473c")] 17 | [assembly: System.Reflection.AssemblyProductAttribute("ch_02_routing")] 18 | [assembly: System.Reflection.AssemblyTitleAttribute("ch_02_routing")] 19 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 20 | 21 | // MSBuild WriteCodeFragment sınıfı tarafından oluşturuldu. 22 | 23 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 6edb5800efa5c5b0bd023bf9c0536aeb5057a922b14e180d1ca77469bef1a908 2 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net8.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = true 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = ch_02_routing 11 | build_property.RootNamespace = ch_02_routing 12 | build_property.ProjectDir = F:\minimal-apis\ch_02_routing\ 13 | build_property.EnableComHosting = 14 | build_property.EnableGeneratedComInterfaceComImportInterop = 15 | build_property.RazorLangVersion = 8.0 16 | build_property.SupportLocalizedComponentNames = 17 | build_property.GenerateRazorMetadataSourceChecksumAttributes = 18 | build_property.MSBuildProjectDirectory = F:\minimal-apis\ch_02_routing 19 | build_property._RazorSourceGeneratorDebug = 20 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.GlobalUsings.g.cs: -------------------------------------------------------------------------------- 1 | // 2 | global using global::Microsoft.AspNetCore.Builder; 3 | global using global::Microsoft.AspNetCore.Hosting; 4 | global using global::Microsoft.AspNetCore.Http; 5 | global using global::Microsoft.AspNetCore.Routing; 6 | global using global::Microsoft.Extensions.Configuration; 7 | global using global::Microsoft.Extensions.DependencyInjection; 8 | global using global::Microsoft.Extensions.Hosting; 9 | global using global::Microsoft.Extensions.Logging; 10 | global using global::System; 11 | global using global::System.Collections.Generic; 12 | global using global::System.IO; 13 | global using global::System.Linq; 14 | global using global::System.Net.Http; 15 | global using global::System.Net.Http.Json; 16 | global using global::System.Threading; 17 | global using global::System.Threading.Tasks; 18 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.MvcApplicationPartsAssemblyInfo.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_routing.MvcApplicationPartsAssemblyInfo.cache -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.MvcApplicationPartsAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | using System; 11 | using System.Reflection; 12 | 13 | [assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("Microsoft.AspNetCore.OpenApi")] 14 | [assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("Swashbuckle.AspNetCore.SwaggerGen")] 15 | 16 | // MSBuild WriteCodeFragment sınıfı tarafından oluşturuldu. 17 | 18 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_routing.assets.cache -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_routing.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 99be0a62e8cfa20b25c27e4c70a4e1b68dc5b0a807f6305936f3943a39f76ca0 2 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_routing.dll -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | 5631757e172a7788f0f8837237134b1025ca9df552593a60c320ff6fabfd48e6 2 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ch_02_routing.pdb -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ch_02_routing.sourcelink.json: -------------------------------------------------------------------------------- 1 | {"documents":{"F:\\minimal-apis\\*":"https://raw.githubusercontent.com/zcomert/minimal-apis/0dea758a2b13177583b882c8c23543ce7d45473c/*"}} -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/ref/ch_02_routing.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/ref/ch_02_routing.dll -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/refint/ch_02_routing.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_02_routing/obj/Debug/net8.0/refint/ch_02_routing.dll -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/staticwebassets.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Hash": "O9viKSExisbYUlX/TK4BeyfY6Uce2QJybptEn3kpGCY=", 4 | "Source": "ch_02_routing", 5 | "BasePath": "_content/ch_02_routing", 6 | "Mode": "Default", 7 | "ManifestType": "Build", 8 | "ReferencedProjectsConfiguration": [], 9 | "DiscoveryPatterns": [], 10 | "Assets": [] 11 | } -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/staticwebassets/msbuild.build.ch_02_routing.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/staticwebassets/msbuild.buildMultiTargeting.ch_02_routing.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /ch_02_routing/obj/Debug/net8.0/staticwebassets/msbuild.buildTransitive.ch_02_routing.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /ch_02_routing/obj/ch_02_routing.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "F:\\minimal-apis\\ch_02_routing\\ch_02_routing.csproj": {} 5 | }, 6 | "projects": { 7 | "F:\\minimal-apis\\ch_02_routing\\ch_02_routing.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "F:\\minimal-apis\\ch_02_routing\\ch_02_routing.csproj", 11 | "projectName": "ch_02_routing", 12 | "projectPath": "F:\\minimal-apis\\ch_02_routing\\ch_02_routing.csproj", 13 | "packagesPath": "C:\\Users\\zafer\\.nuget\\packages\\", 14 | "outputPath": "F:\\minimal-apis\\ch_02_routing\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "configFilePaths": [ 17 | "C:\\Users\\zafer\\AppData\\Roaming\\NuGet\\NuGet.Config", 18 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 19 | ], 20 | "originalTargetFrameworks": [ 21 | "net8.0" 22 | ], 23 | "sources": { 24 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 25 | "https://api.nuget.org/v3/index.json": {} 26 | }, 27 | "frameworks": { 28 | "net8.0": { 29 | "targetAlias": "net8.0", 30 | "projectReferences": {} 31 | } 32 | }, 33 | "warningProperties": { 34 | "warnAsError": [ 35 | "NU1605" 36 | ] 37 | }, 38 | "restoreAuditProperties": { 39 | "enableAudit": "true", 40 | "auditLevel": "low", 41 | "auditMode": "direct" 42 | } 43 | }, 44 | "frameworks": { 45 | "net8.0": { 46 | "targetAlias": "net8.0", 47 | "dependencies": { 48 | "Microsoft.AspNetCore.OpenApi": { 49 | "target": "Package", 50 | "version": "[8.0.2, )" 51 | }, 52 | "Swashbuckle.AspNetCore": { 53 | "target": "Package", 54 | "version": "[6.4.0, )" 55 | } 56 | }, 57 | "imports": [ 58 | "net461", 59 | "net462", 60 | "net47", 61 | "net471", 62 | "net472", 63 | "net48", 64 | "net481" 65 | ], 66 | "assetTargetFallback": true, 67 | "warn": true, 68 | "frameworkReferences": { 69 | "Microsoft.AspNetCore.App": { 70 | "privateAssets": "none" 71 | }, 72 | "Microsoft.NETCore.App": { 73 | "privateAssets": "all" 74 | } 75 | }, 76 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.201/PortableRuntimeIdentifierGraph.json" 77 | } 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /ch_02_routing/obj/ch_02_routing.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\zafer\.nuget\packages\ 9 | PackageReference 10 | 6.9.1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | C:\Users\zafer\.nuget\packages\microsoft.extensions.apidescription.server\6.0.5 21 | 22 | -------------------------------------------------------------------------------- /ch_02_routing/obj/ch_02_routing.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ch_02_routing/obj/project.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "dgSpecHash": "5wylAzJK8ddcxhGMTYLeyF+B6ApbdBwp65i3qZEmU5wNj19U9ZFV9qeNUMEDKu9fytmhve6tM9Om11SEMblOcg==", 4 | "success": true, 5 | "projectFilePath": "F:\\minimal-apis\\ch_02_routing\\ch_02_routing.csproj", 6 | "expectedPackageFiles": [ 7 | "C:\\Users\\zafer\\.nuget\\packages\\microsoft.aspnetcore.openapi\\8.0.2\\microsoft.aspnetcore.openapi.8.0.2.nupkg.sha512", 8 | "C:\\Users\\zafer\\.nuget\\packages\\microsoft.extensions.apidescription.server\\6.0.5\\microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512", 9 | "C:\\Users\\zafer\\.nuget\\packages\\microsoft.openapi\\1.4.3\\microsoft.openapi.1.4.3.nupkg.sha512", 10 | "C:\\Users\\zafer\\.nuget\\packages\\swashbuckle.aspnetcore\\6.4.0\\swashbuckle.aspnetcore.6.4.0.nupkg.sha512", 11 | "C:\\Users\\zafer\\.nuget\\packages\\swashbuckle.aspnetcore.swagger\\6.4.0\\swashbuckle.aspnetcore.swagger.6.4.0.nupkg.sha512", 12 | "C:\\Users\\zafer\\.nuget\\packages\\swashbuckle.aspnetcore.swaggergen\\6.4.0\\swashbuckle.aspnetcore.swaggergen.6.4.0.nupkg.sha512", 13 | "C:\\Users\\zafer\\.nuget\\packages\\swashbuckle.aspnetcore.swaggerui\\6.4.0\\swashbuckle.aspnetcore.swaggerui.6.4.0.nupkg.sha512" 14 | ], 15 | "logs": [] 16 | } -------------------------------------------------------------------------------- /ch_03_route_parameters/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | builder.Services.AddEndpointsApiExplorer(); 4 | builder.Services.AddSwaggerGen(); 5 | 6 | var app = builder.Build(); 7 | 8 | if (app.Environment.IsDevelopment()) 9 | { 10 | app.UseSwagger(); 11 | app.UseSwaggerUI(); 12 | } 13 | 14 | app.UseHttpsRedirection(); 15 | 16 | app.MapGet("/employees", () => new Employee().GetAllEmployees()); 17 | app.MapGet("/employees/search", (string q) => Employee.Search(q)); 18 | app.MapGet("/employees/{id:int}", (int id) => new Employee().GetOneEmployee(id)); 19 | app.MapPost("/employees", (Employee emp) => Employee.CreateOneEmployee(emp)); 20 | 21 | app.Run(); 22 | 23 | 24 | class Employee 25 | { 26 | public int Id { get; set; } 27 | public String? FullName { get; set; } 28 | public Decimal Salary { get; set; } 29 | 30 | private static List Employees = new List() 31 | { 32 | new Employee() { Id = 1, FullName = "Ahmet Güneş", Salary=90_000}, 33 | new Employee() { Id = 2, FullName = "Sıla Bulut", Salary=70_000}, 34 | new Employee() { Id = 3, FullName = "Can Tan", Salary=95_000}, 35 | }; 36 | 37 | public List GetAllEmployees() => Employees; 38 | public Employee? GetOneEmployee(int id) => Employees 39 | .SingleOrDefault(e => e.Id.Equals(id)); 40 | 41 | public static Employee CreateOneEmployee(Employee employee) 42 | { 43 | Employees.Add(employee); 44 | return employee; 45 | } 46 | 47 | public static List? Search(string q) 48 | { 49 | return Employees 50 | .Where(e => e.FullName != null && 51 | e.FullName.ToLower().Contains(q.ToLower())) 52 | .ToList(); 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /ch_03_route_parameters/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:18048", 8 | "sslPort": 44360 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5170", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7262;http://localhost:5170", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_03_route_parameters/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_03_route_parameters/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_03_route_parameters/ch_03_route_parameters.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_03_route_parameters/ch_03_route_parameters.http: -------------------------------------------------------------------------------- 1 | @ch_03_route_parameters_HostAddress = http://localhost:5170 2 | 3 | GET {{ch_03_route_parameters_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_03_route_parameters/ch_03_route_parameters.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_03_route_parameters", "ch_03_route_parameters.csproj", "{24123FA6-877E-4F27-A3BF-C24BEC56AF76}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {24123FA6-877E-4F27-A3BF-C24BEC56AF76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {24123FA6-877E-4F27-A3BF-C24BEC56AF76}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {24123FA6-877E-4F27-A3BF-C24BEC56AF76}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {24123FA6-877E-4F27-A3BF-C24BEC56AF76}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {6B23A96D-5263-41D0-AC53-CE6E6EE7C726} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5278 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookApi", "BookApi.csproj", "{7D1440AC-C986-4176-9DFC-66594125DAE5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7D1440AC-C986-4176-9DFC-66594125DAE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {7D1440AC-C986-4176-9DFC-66594125DAE5}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {7D1440AC-C986-4176-9DFC-66594125DAE5}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {7D1440AC-C986-4176-9DFC-66594125DAE5}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {02901178-A461-4868-8B56-1F61D8B8E0FF} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/Models/ErrorModel.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | class ErroDetails { 3 | - StatusCode: int 4 | - Message: string? 5 | + ToString(): string 6 | } 7 | 8 | abstract class NotFoundException { 9 | - NotFoundException(message: string) 10 | } 11 | 12 | class BookNotFoundException { 13 | - BookNotFoundException(id: int) 14 | } 15 | 16 | hide empty members 17 | 18 | NotFoundException <|-- BookNotFoundException 19 | 20 | 21 | @enduml 22 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:7750", 8 | "sslPort": 44338 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5278", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7296;http://localhost:5278", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_04_results/BookApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_05_errors/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:33822", 8 | "sslPort": 44387 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5120", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7181;http://localhost:5120", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_05_errors/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_05_errors/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_05_errors/ch_05_errors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_05_errors/ch_05_errors.http: -------------------------------------------------------------------------------- 1 | @ch_05_errors_HostAddress = http://localhost:5120 2 | 3 | GET {{ch_05_errors_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_05_errors/ch_05_errors.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_05_errors", "ch_05_errors.csproj", "{D3B3B5D2-C410-4F6F-AC37-A82D6425A19D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D3B3B5D2-C410-4F6F-AC37-A82D6425A19D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D3B3B5D2-C410-4F6F-AC37-A82D6425A19D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D3B3B5D2-C410-4F6F-AC37-A82D6425A19D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D3B3B5D2-C410-4F6F-AC37-A82D6425A19D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {AD1463B8-C54A-4CF3-BCA3-36669660DC5C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_06_cors/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:15774", 8 | "sslPort": 44306 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5295", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7269;http://localhost:5295", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_06_cors/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_06_cors/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_06_cors/ch_06_cors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_06_cors/ch_06_cors.http: -------------------------------------------------------------------------------- 1 | @ch_06_cors_HostAddress = http://localhost:5295 2 | 3 | GET {{ch_06_cors_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_06_cors/ch_06_cors.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_06_cors", "ch_06_cors.csproj", "{C111D298-0410-48F7-94A2-EA0F6A3F4A12}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C111D298-0410-48F7-94A2-EA0F6A3F4A12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {C111D298-0410-48F7-94A2-EA0F6A3F4A12}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {C111D298-0410-48F7-94A2-EA0F6A3F4A12}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {C111D298-0410-48F7-94A2-EA0F6A3F4A12}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D4AE47CB-429B-4089-8612-D14EC84249F8} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_07_swagger/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:64685", 8 | "sslPort": 44314 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5112", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7105;http://localhost:5112", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_07_swagger/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_07_swagger/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_07_swagger/ch_07_swagger.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_07_swagger/ch_07_swagger.http: -------------------------------------------------------------------------------- 1 | @ch_07_swagger_HostAddress = http://localhost:5112 2 | 3 | GET {{ch_07_swagger_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_07_swagger/ch_07_swagger.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_07_swagger", "ch_07_swagger.csproj", "{703F2A72-F77C-4A4F-BD12-FDD95EE0A287}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {703F2A72-F77C-4A4F-BD12-FDD95EE0A287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {703F2A72-F77C-4A4F-BD12-FDD95EE0A287}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {703F2A72-F77C-4A4F-BD12-FDD95EE0A287}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {703F2A72-F77C-4A4F-BD12-FDD95EE0A287}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D61DF3D0-CDAB-4BDA-9C92-24EB67D7128B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_08_validation/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:1614", 8 | "sslPort": 44305 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5160", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7267;http://localhost:5160", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_08_validation/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_08_validation/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_08_validation/ch_08_validation.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_08_validation/ch_08_validation.http: -------------------------------------------------------------------------------- 1 | @ch_08_validation_HostAddress = http://localhost:5160 2 | 3 | GET {{ch_08_validation_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_08_validation/ch_08_validation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_08_validation", "ch_08_validation.csproj", "{4155FC17-32DB-460A-A194-F4C91FBD23AE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4155FC17-32DB-460A-A194-F4C91FBD23AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4155FC17-32DB-460A-A194-F4C91FBD23AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4155FC17-32DB-460A-A194-F4C91FBD23AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4155FC17-32DB-460A-A194-F4C91FBD23AE}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9FD9491E-BDD4-4CB4-8998-E70857E352E0} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_09_di/Models/Model.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | title BookApi 3 | 4 | class Book{ 5 | +id 6 | +title 7 | +price 8 | } 9 | 10 | abstract class NotFoundException { 11 | +NotFoundException(message: String) 12 | } 13 | 14 | class BookNotFoundException { 15 | +BookNotFoundException(id: int) 16 | } 17 | 18 | class BookService 19 | { 20 | -bookList:List 21 | -- 22 | +Count:int 23 | -- 24 | +GetBooks():List 25 | +GetBookById(int:i):Book 26 | +AddBook(item:Book) 27 | +UpdateBook(id:int, item:Book) 28 | +DeleteBook(id:int) 29 | 30 | } 31 | 32 | interface IBookService 33 | { 34 | +Count:int 35 | +GetBooks():List 36 | +GetBookById(id:int):Book 37 | +AddBook(item:Book):void 38 | +UpdateBook(id:int, item:Book):Book 39 | +DeleteBook(id:int):void 40 | } 41 | 42 | BookService .up.|> IBookService : "<>" 43 | BookNotFoundException .up.|> NotFoundException : "<>" 44 | hide empty members -------------------------------------------------------------------------------- /ch_09_di/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:24880", 8 | "sslPort": 44357 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5023", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7227;http://localhost:5023", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_09_di/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_09_di/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_09_di/ch_09_di.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_09_di/ch_09_di.http: -------------------------------------------------------------------------------- 1 | @ch_09_di_HostAddress = http://localhost:5023 2 | 3 | GET {{ch_09_di_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_09_di/ch_09_di.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_09_di", "ch_09_di.csproj", "{7188039A-25EF-49F8-BB48-E93B9B706512}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7188039A-25EF-49F8-BB48-E93B9B706512}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {7188039A-25EF-49F8-BB48-E93B9B706512}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {7188039A-25EF-49F8-BB48-E93B9B706512}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {7188039A-25EF-49F8-BB48-E93B9B706512}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D9525FF3-AEC4-4E95-A6EE-699122EE2626} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/Models/Model.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | title BookApi 3 | 4 | class Book{ 5 | +id 6 | +title 7 | +price 8 | } 9 | 10 | abstract class NotFoundException { 11 | +NotFoundException(message: String) 12 | } 13 | 14 | class BookNotFoundException { 15 | +BookNotFoundException(id: int) 16 | } 17 | 18 | class BookService 19 | { 20 | -bookList:List 21 | -- 22 | +Count:int 23 | -- 24 | +GetBooks():List 25 | +GetBookById(int:i):Book 26 | +AddBook(item:Book) 27 | +UpdateBook(id:int, item:Book) 28 | +DeleteBook(id:int) 29 | 30 | } 31 | 32 | interface IBookService 33 | { 34 | +Count:int 35 | +GetBooks():List 36 | +GetBookById(id:int):Book 37 | +AddBook(item:Book):void 38 | +UpdateBook(id:int, item:Book):Book 39 | +DeleteBook(id:int):void 40 | } 41 | 42 | BookService .up.|> IBookService : "<>" 43 | BookNotFoundException .up.|> NotFoundException : "<>" 44 | hide empty members -------------------------------------------------------------------------------- /ch_10_di_and_interface/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:54509", 8 | "sslPort": 44309 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5173", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7025;http://localhost:5173", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/ch_10_di_and_interface.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/ch_10_di_and_interface.http: -------------------------------------------------------------------------------- 1 | @ch_10_di_and_interface_HostAddress = http://localhost:5173 2 | 3 | GET {{ch_10_di_and_interface_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_10_di_and_interface/ch_10_di_and_interface.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_10_di_and_interface", "ch_10_di_and_interface.csproj", "{D0D8CD6C-ED76-4BDB-A0D1-EC93C0B3E776}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D0D8CD6C-ED76-4BDB-A0D1-EC93C0B3E776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D0D8CD6C-ED76-4BDB-A0D1-EC93C0B3E776}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D0D8CD6C-ED76-4BDB-A0D1-EC93C0B3E776}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D0D8CD6C-ED76-4BDB-A0D1-EC93C0B3E776}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D1664D6D-7DC2-471B-B445-6E0E55F4D907} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_11_dal/Migrations/20241120075446_start.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Migrations; 5 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 6 | using Repositories; 7 | 8 | #nullable disable 9 | 10 | namespace ch_11_dal.Migrations 11 | { 12 | [DbContext(typeof(RepositoryContext))] 13 | [Migration("20241120075446_start")] 14 | partial class start 15 | { 16 | /// 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); 21 | 22 | modelBuilder.Entity("Book", b => 23 | { 24 | b.Property("Id") 25 | .ValueGeneratedOnAdd() 26 | .HasColumnType("INTEGER"); 27 | 28 | b.Property("Price") 29 | .HasColumnType("TEXT"); 30 | 31 | b.Property("Title") 32 | .HasMaxLength(25) 33 | .HasColumnType("TEXT"); 34 | 35 | b.HasKey("Id"); 36 | 37 | b.ToTable("Books"); 38 | }); 39 | #pragma warning restore 612, 618 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ch_11_dal/Migrations/20241120075446_start.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace ch_11_dal.Migrations 6 | { 7 | /// 8 | public partial class start : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.CreateTable( 14 | name: "Books", 15 | columns: table => new 16 | { 17 | Id = table.Column(type: "INTEGER", nullable: false) 18 | .Annotation("Sqlite:Autoincrement", true), 19 | Title = table.Column(type: "TEXT", maxLength: 25, nullable: true), 20 | Price = table.Column(type: "TEXT", nullable: false) 21 | }, 22 | constraints: table => 23 | { 24 | table.PrimaryKey("PK_Books", x => x.Id); 25 | }); 26 | } 27 | 28 | /// 29 | protected override void Down(MigrationBuilder migrationBuilder) 30 | { 31 | migrationBuilder.DropTable( 32 | name: "Books"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch_11_dal/Migrations/20241120080341_seed-data.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Migrations; 5 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 6 | using Repositories; 7 | 8 | #nullable disable 9 | 10 | namespace ch_11_dal.Migrations 11 | { 12 | [DbContext(typeof(RepositoryContext))] 13 | [Migration("20241120080341_seed-data")] 14 | partial class seeddata 15 | { 16 | /// 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); 21 | 22 | modelBuilder.Entity("Book", b => 23 | { 24 | b.Property("Id") 25 | .ValueGeneratedOnAdd() 26 | .HasColumnType("INTEGER"); 27 | 28 | b.Property("Price") 29 | .HasColumnType("TEXT"); 30 | 31 | b.Property("Title") 32 | .HasMaxLength(25) 33 | .HasColumnType("TEXT"); 34 | 35 | b.HasKey("Id"); 36 | 37 | b.ToTable("Books"); 38 | 39 | b.HasData( 40 | new 41 | { 42 | Id = 1, 43 | Price = 20.00m, 44 | Title = "Devlet" 45 | }, 46 | new 47 | { 48 | Id = 2, 49 | Price = 15.50m, 50 | Title = "Ateşten Gömlek" 51 | }, 52 | new 53 | { 54 | Id = 3, 55 | Price = 18.75m, 56 | Title = "Huzur" 57 | }); 58 | }); 59 | #pragma warning restore 612, 618 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch_11_dal/Migrations/20241120080341_seed-data.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | #pragma warning disable CA1814 // Prefer jagged arrays over multidimensional 6 | 7 | namespace ch_11_dal.Migrations 8 | { 9 | /// 10 | public partial class seeddata : Migration 11 | { 12 | /// 13 | protected override void Up(MigrationBuilder migrationBuilder) 14 | { 15 | migrationBuilder.InsertData( 16 | table: "Books", 17 | columns: new[] { "Id", "Price", "Title" }, 18 | values: new object[,] 19 | { 20 | { 1, 20.00m, "Devlet" }, 21 | { 2, 15.50m, "Ateşten Gömlek" }, 22 | { 3, 18.75m, "Huzur" } 23 | }); 24 | } 25 | 26 | /// 27 | protected override void Down(MigrationBuilder migrationBuilder) 28 | { 29 | migrationBuilder.DeleteData( 30 | table: "Books", 31 | keyColumn: "Id", 32 | keyValue: 1); 33 | 34 | migrationBuilder.DeleteData( 35 | table: "Books", 36 | keyColumn: "Id", 37 | keyValue: 2); 38 | 39 | migrationBuilder.DeleteData( 40 | table: "Books", 41 | keyColumn: "Id", 42 | keyValue: 3); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch_11_dal/Migrations/RepositoryContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 5 | using Repositories; 6 | 7 | #nullable disable 8 | 9 | namespace ch_11_dal.Migrations 10 | { 11 | [DbContext(typeof(RepositoryContext))] 12 | partial class RepositoryContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); 18 | 19 | modelBuilder.Entity("Book", b => 20 | { 21 | b.Property("Id") 22 | .ValueGeneratedOnAdd() 23 | .HasColumnType("INTEGER"); 24 | 25 | b.Property("Price") 26 | .HasColumnType("TEXT"); 27 | 28 | b.Property("Title") 29 | .HasMaxLength(25) 30 | .HasColumnType("TEXT"); 31 | 32 | b.HasKey("Id"); 33 | 34 | b.ToTable("Books"); 35 | 36 | b.HasData( 37 | new 38 | { 39 | Id = 1, 40 | Price = 20.00m, 41 | Title = "Devlet" 42 | }, 43 | new 44 | { 45 | Id = 2, 46 | Price = 15.50m, 47 | Title = "Ateşten Gömlek" 48 | }, 49 | new 50 | { 51 | Id = 3, 52 | Price = 18.75m, 53 | Title = "Huzur" 54 | }); 55 | }); 56 | #pragma warning restore 612, 618 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ch_11_dal/Models/Model.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | title BookApi 3 | 4 | package Repositories 5 | { 6 | class RepositoryContext { 7 | +Books:DbSet 8 | +RepositoryContext(options:DbContextOptions) 9 | +OnModelCreating(modelBuilder:ModelBuilder) 10 | } 11 | } 12 | 13 | class Book{ 14 | +id 15 | +title 16 | +price 17 | } 18 | 19 | abstract class NotFoundException { 20 | +NotFoundException(message: String) 21 | } 22 | 23 | class BookNotFoundException { 24 | +BookNotFoundException(id: int) 25 | } 26 | 27 | class BookService 28 | { 29 | -bookList:List 30 | -- 31 | +Count:int 32 | -- 33 | +GetBooks():List 34 | +GetBookById(int:i):Book 35 | +AddBook(item:Book) 36 | +UpdateBook(id:int, item:Book) 37 | +DeleteBook(id:int) 38 | 39 | } 40 | 41 | interface IBookService 42 | { 43 | +Count:int 44 | +GetBooks():List 45 | +GetBookById(id:int):Book 46 | +AddBook(item:Book):void 47 | +UpdateBook(id:int, item:Book):Book 48 | +DeleteBook(id:int):void 49 | } 50 | 51 | BookService .up.|> IBookService : "<>" 52 | BookNotFoundException .up.|> NotFoundException : "<>" 53 | 54 | RepositoryContext -up-|> DbContext : "<>" 55 | hide empty members -------------------------------------------------------------------------------- /ch_11_dal/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:45915", 8 | "sslPort": 44307 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5216", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7157;http://localhost:5216", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_11_dal/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Repositories; 4 | 5 | public class RepositoryContext : DbContext 6 | { 7 | public DbSet Books { get; set; } 8 | public RepositoryContext(DbContextOptions options) 9 | : base(options) 10 | { 11 | 12 | } 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | base.OnModelCreating(modelBuilder); 17 | modelBuilder.Entity().HasData( 18 | new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 19 | new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 20 | new Book { Id = 3, Title = "Huzur", Price = 18.75M } 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /ch_11_dal/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_11_dal/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | } 12 | } -------------------------------------------------------------------------------- /ch_11_dal/ch_11_dal.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | all 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch_11_dal/ch_11_dal.http: -------------------------------------------------------------------------------- 1 | @ch_11_dal_HostAddress = http://localhost:5216 2 | 3 | GET {{ch_11_dal_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_11_dal/ch_11_dal.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_11_dal", "ch_11_dal.csproj", "{0ED6855F-C1EC-4FB5-82CE-0CB0F64ABA99}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0ED6855F-C1EC-4FB5-82CE-0CB0F64ABA99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0ED6855F-C1EC-4FB5-82CE-0CB0F64ABA99}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0ED6855F-C1EC-4FB5-82CE-0CB0F64ABA99}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0ED6855F-C1EC-4FB5-82CE-0CB0F64ABA99}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {DA2C346F-7682-4B27-9A8F-CCEE278522A7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_11_dal/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_11_dal/database.db -------------------------------------------------------------------------------- /ch_12_repo_in_use/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | namespace Abstracts; 2 | 3 | public interface IBookService 4 | { 5 | int Count { get; } 6 | List GetBooks(); 7 | Book? GetBookById(int id); 8 | void AddBook(Book item); 9 | Book UpdateBook(int id, Book item); 10 | void DeleteBook(int id); 11 | } 12 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Migrations/20241120094804_start.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Migrations; 5 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 6 | using Repositories; 7 | 8 | #nullable disable 9 | 10 | namespace ch_12_repo_in_use.Migrations 11 | { 12 | [DbContext(typeof(RepositoryContext))] 13 | [Migration("20241120094804_start")] 14 | partial class start 15 | { 16 | /// 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); 21 | 22 | modelBuilder.Entity("Book", b => 23 | { 24 | b.Property("Id") 25 | .ValueGeneratedOnAdd() 26 | .HasColumnType("INTEGER"); 27 | 28 | b.Property("Price") 29 | .HasColumnType("TEXT"); 30 | 31 | b.Property("Title") 32 | .HasMaxLength(25) 33 | .HasColumnType("TEXT"); 34 | 35 | b.HasKey("Id"); 36 | 37 | b.ToTable("Books"); 38 | 39 | b.HasData( 40 | new 41 | { 42 | Id = 1, 43 | Price = 20.00m, 44 | Title = "Devlet" 45 | }, 46 | new 47 | { 48 | Id = 2, 49 | Price = 15.50m, 50 | Title = "Ateşten Gömlek" 51 | }, 52 | new 53 | { 54 | Id = 3, 55 | Price = 18.75m, 56 | Title = "Huzur" 57 | }); 58 | }); 59 | #pragma warning restore 612, 618 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Migrations/20241120094804_start.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | #pragma warning disable CA1814 // Prefer jagged arrays over multidimensional 6 | 7 | namespace ch_12_repo_in_use.Migrations 8 | { 9 | /// 10 | public partial class start : Migration 11 | { 12 | /// 13 | protected override void Up(MigrationBuilder migrationBuilder) 14 | { 15 | migrationBuilder.CreateTable( 16 | name: "Books", 17 | columns: table => new 18 | { 19 | Id = table.Column(type: "INTEGER", nullable: false) 20 | .Annotation("Sqlite:Autoincrement", true), 21 | Title = table.Column(type: "TEXT", maxLength: 25, nullable: true), 22 | Price = table.Column(type: "TEXT", nullable: false) 23 | }, 24 | constraints: table => 25 | { 26 | table.PrimaryKey("PK_Books", x => x.Id); 27 | }); 28 | 29 | migrationBuilder.InsertData( 30 | table: "Books", 31 | columns: new[] { "Id", "Price", "Title" }, 32 | values: new object[,] 33 | { 34 | { 1, 20.00m, "Devlet" }, 35 | { 2, 15.50m, "Ateşten Gömlek" }, 36 | { 3, 18.75m, "Huzur" } 37 | }); 38 | } 39 | 40 | /// 41 | protected override void Down(MigrationBuilder migrationBuilder) 42 | { 43 | migrationBuilder.DropTable( 44 | name: "Books"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Migrations/RepositoryContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 5 | using Repositories; 6 | 7 | #nullable disable 8 | 9 | namespace ch_12_repo_in_use.Migrations 10 | { 11 | [DbContext(typeof(RepositoryContext))] 12 | partial class RepositoryContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); 18 | 19 | modelBuilder.Entity("Book", b => 20 | { 21 | b.Property("Id") 22 | .ValueGeneratedOnAdd() 23 | .HasColumnType("INTEGER"); 24 | 25 | b.Property("Price") 26 | .HasColumnType("TEXT"); 27 | 28 | b.Property("Title") 29 | .HasMaxLength(25) 30 | .HasColumnType("TEXT"); 31 | 32 | b.HasKey("Id"); 33 | 34 | b.ToTable("Books"); 35 | 36 | b.HasData( 37 | new 38 | { 39 | Id = 1, 40 | Price = 20.00m, 41 | Title = "Devlet" 42 | }, 43 | new 44 | { 45 | Id = 2, 46 | Price = 15.50m, 47 | Title = "Ateşten Gömlek" 48 | }, 49 | new 50 | { 51 | Id = 3, 52 | Price = 18.75m, 53 | Title = "Huzur" 54 | }); 55 | }); 56 | #pragma warning restore 612, 618 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Models/Model.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | title BookApi 3 | 4 | 5 | 6 | class Book{ 7 | +id 8 | +title 9 | +price 10 | } 11 | 12 | abstract class NotFoundException { 13 | +NotFoundException(message: String) 14 | } 15 | 16 | class BookNotFoundException { 17 | +BookNotFoundException(id: int) 18 | } 19 | 20 | package Repositories 21 | { 22 | class RepositoryContext { 23 | +Books:DbSet 24 | +RepositoryContext(options:DbContextOptions) 25 | +OnModelCreating(modelBuilder:ModelBuilder) 26 | } 27 | class BookRepository { 28 | -context:RepositoryContext 29 | +Get(id):Book? 30 | +GetAll():List 31 | +Add(item:Book) 32 | +Remove(item:Book) 33 | +Update(item:Book) 34 | } 35 | } 36 | 37 | package Services 38 | { 39 | class BookService 40 | { 41 | -bookList:List 42 | -- 43 | +Count:int 44 | -- 45 | +GetBooks():List 46 | +GetBookById(int:i):Book 47 | +AddBook(item:Book) 48 | +UpdateBook(id:int, item:Book) 49 | +DeleteBook(id:int) 50 | 51 | } 52 | class BookServiceV2 53 | { 54 | -context:RepositoryContext 55 | -- 56 | +Count:int 57 | -- 58 | +GetBooks():List 59 | +GetBookById(int:i):Book 60 | +AddBook(item:Book) 61 | +UpdateBook(id:int, item:Book) 62 | +DeleteBook(id:int) 63 | 64 | } 65 | class BookServiceV3 66 | { 67 | -context:BookRepository 68 | -- 69 | +Count:int 70 | -- 71 | +GetBooks():List 72 | +GetBookById(int:i):Book 73 | +AddBook(item:Book) 74 | +UpdateBook(id:int, item:Book) 75 | +DeleteBook(id:int) 76 | } 77 | } 78 | 79 | 80 | package Abstracts 81 | { 82 | interface IBookService 83 | { 84 | +Count:int 85 | +GetBooks():List 86 | +GetBookById(id:int):Book 87 | +AddBook(item:Book):void 88 | +UpdateBook(id:int, item:Book):Book 89 | +DeleteBook(id:int):void 90 | } 91 | } 92 | 93 | BookService .up.|> IBookService : "<>" 94 | BookServiceV2 .up.|> IBookService : "<>" 95 | BookServiceV3 .up.|> IBookService : "<>" 96 | BookNotFoundException .up.|> NotFoundException : "<>" 97 | 98 | RepositoryContext -up-|> DbContext : "<>" 99 | hide empty members -------------------------------------------------------------------------------- /ch_12_repo_in_use/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:58676", 8 | "sslPort": 44375 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5235", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7211;http://localhost:5235", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | namespace Repositories; 2 | 3 | public class BookRepository 4 | { 5 | private readonly RepositoryContext _context; 6 | 7 | public BookRepository(RepositoryContext context) 8 | { 9 | _context = context; 10 | } 11 | 12 | public Book? Get(int id) => 13 | _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 14 | 15 | public List GetAll() => 16 | _context.Books.ToList(); 17 | 18 | public void Add(Book item) 19 | { 20 | _context.Books.Add(item); 21 | _context.SaveChanges(); 22 | } 23 | public void Remove(Book item) 24 | { 25 | _context.Remove(item); 26 | _context.SaveChanges(); 27 | } 28 | public void Update(Book item) 29 | { 30 | _context.Books.Update(item); 31 | _context.SaveChanges(); 32 | } 33 | } -------------------------------------------------------------------------------- /ch_12_repo_in_use/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Repositories; 4 | 5 | public class RepositoryContext : DbContext 6 | { 7 | public DbSet Books { get; set; } 8 | public RepositoryContext(DbContextOptions options) 9 | : base(options) 10 | { 11 | 12 | } 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | base.OnModelCreating(modelBuilder); 17 | modelBuilder.Entity().HasData( 18 | new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 19 | new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 20 | new Book { Id = 3, Title = "Huzur", Price = 18.75M } 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /ch_12_repo_in_use/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | using Abstracts; 2 | 3 | namespace Services; 4 | 5 | public class BookService : IBookService 6 | { 7 | private readonly List _bookList; 8 | public BookService() 9 | { 10 | // seed data 11 | _bookList = new List() 12 | { 13 | new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 14 | new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 15 | new Book { Id = 3, Title = "Huzur", Price = 18.75M } 16 | }; 17 | } 18 | 19 | public List GetBooks() => _bookList; 20 | 21 | public int Count => _bookList.Count; 22 | 23 | public Book? GetBookById(int id) => 24 | _bookList.FirstOrDefault(b => b.Id.Equals(id)); 25 | 26 | public void AddBook(Book newBook) 27 | { 28 | newBook.Id = _bookList.Max(b => b.Id) + 1; 29 | _bookList.Add(newBook); 30 | } 31 | 32 | public Book UpdateBook(int id, Book updateBook) 33 | { 34 | var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 35 | if (book is null) 36 | { 37 | throw new BookNotFoundException(id); 38 | } 39 | 40 | book.Title = updateBook.Title; 41 | book.Price = updateBook.Price; 42 | 43 | return book; 44 | } 45 | 46 | public void DeleteBook(int id) 47 | { 48 | var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 49 | if (book is not null) 50 | { 51 | _bookList.Remove(book); 52 | } 53 | else 54 | { 55 | throw new BookNotFoundException(id); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /ch_12_repo_in_use/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Mime; 2 | using Abstracts; 3 | using Repositories; 4 | 5 | namespace Services; 6 | 7 | public class BookServiceV2 : IBookService 8 | { 9 | private readonly RepositoryContext _context; 10 | 11 | public BookServiceV2(RepositoryContext context) 12 | { 13 | _context = context; 14 | } 15 | 16 | public int Count => _context.Books.ToList().Count; 17 | 18 | public void AddBook(Book item) 19 | { 20 | _context.Books.Add(item); 21 | _context.SaveChanges(); 22 | } 23 | 24 | public void DeleteBook(int id) 25 | { 26 | var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 27 | if (book is not null) 28 | { 29 | _context.Books.Remove(book); 30 | _context.SaveChanges(); 31 | } 32 | else 33 | { 34 | throw new BookNotFoundException(id); 35 | } 36 | } 37 | 38 | public Book? GetBookById(int id) => 39 | _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 40 | 41 | public List GetBooks() => 42 | _context.Books.ToList(); 43 | 44 | 45 | public Book UpdateBook(int id, Book item) 46 | { 47 | var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 48 | if (book is null) 49 | { 50 | throw new BookNotFoundException(id); 51 | } 52 | 53 | book.Title = item.Title; 54 | book.Price = item.Price; 55 | _context.SaveChanges(); 56 | return book; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using Abstracts; 2 | using Repositories; 3 | 4 | namespace Services; 5 | 6 | public class BookServiceV3 : IBookService 7 | { 8 | private readonly BookRepository _bookRepo; 9 | 10 | public BookServiceV3(BookRepository bookRepo) 11 | { 12 | _bookRepo = bookRepo; 13 | } 14 | 15 | public int Count => _bookRepo.GetAll().Count; 16 | 17 | public void AddBook(Book item) 18 | { 19 | _bookRepo.Add(item); 20 | } 21 | 22 | public void DeleteBook(int id) 23 | { 24 | var book = _bookRepo.Get(id); 25 | if (book is not null) 26 | _bookRepo.Remove(book); 27 | else 28 | throw new BookNotFoundException(id); 29 | } 30 | 31 | public Book? GetBookById(int id) => 32 | _bookRepo.Get(id); 33 | 34 | 35 | public List GetBooks() => 36 | _bookRepo.GetAll(); 37 | 38 | 39 | public Book UpdateBook(int id, Book item) 40 | { 41 | var book = _bookRepo.Get(id); 42 | if (book is null) 43 | { 44 | throw new BookNotFoundException(id); 45 | } 46 | 47 | book.Title = item.Title; 48 | book.Price = item.Price; 49 | _bookRepo.Update(book); 50 | return book; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | } 12 | } -------------------------------------------------------------------------------- /ch_12_repo_in_use/ch_12_repo_in_use.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | all 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/ch_12_repo_in_use.http: -------------------------------------------------------------------------------- 1 | @ch_12_repo_in_use_HostAddress = http://localhost:5235 2 | 3 | GET {{ch_12_repo_in_use_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/ch_12_repo_in_use.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ch_12_repo_in_use", "ch_12_repo_in_use.csproj", "{EF1DCBD8-D066-48B3-8A88-8D829E349E19}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {EF1DCBD8-D066-48B3-8A88-8D829E349E19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {EF1DCBD8-D066-48B3-8A88-8D829E349E19}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {EF1DCBD8-D066-48B3-8A88-8D829E349E19}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {EF1DCBD8-D066-48B3-8A88-8D829E349E19}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {15439E29-4137-4AF6-8092-9FDED591B798} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ch_12_repo_in_use/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_12_repo_in_use/database.db -------------------------------------------------------------------------------- /ch_13_automapper/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Entities.DTOs; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IBookService 7 | { 8 | int Count { get; } 9 | List GetBooks(); 10 | Book? GetBookById(int id); 11 | Book AddBook(BookDtoForInsertion item); 12 | Book UpdateBook(int id, BookDtoForUpdate item); 13 | void DeleteBook(int id); 14 | } 15 | -------------------------------------------------------------------------------- /ch_13_automapper/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch_13_automapper/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5202 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_13_automapper/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookApi", "BookApi.csproj", "{565B12F3-B124-41A2-AC83-5028715780A1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ch_13_automapper/Configuration/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Entities; 3 | using Entities.DTOs; 4 | 5 | namespace Configuration; 6 | 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap().ReverseMap(); 12 | CreateMap().ReverseMap(); 13 | } 14 | } -------------------------------------------------------------------------------- /ch_13_automapper/Entities/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities; 4 | 5 | public class Book 6 | { 7 | public int Id { get; set; } 8 | 9 | public String? Title { get; set; } 10 | 11 | public Decimal Price { get; set; } 12 | } -------------------------------------------------------------------------------- /ch_13_automapper/Entities/DTOs/BookDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public abstract record BookDto 6 | { 7 | [MinLength(2, ErrorMessage = "The title should include at least two characters.")] 8 | [MaxLength(25, ErrorMessage = "The title must be 25 characters or less.")] 9 | public String Title { get; init; } 10 | 11 | [Range(1, 100, ErrorMessage = "Price must be between 1 and 100.")] 12 | public Decimal Price { get; init; } 13 | } -------------------------------------------------------------------------------- /ch_13_automapper/Entities/DTOs/BookDtoForInsertion.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForInsertion : BookDto 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_13_automapper/Entities/DTOs/BookDtoForUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForUpdate : BookDto 6 | { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ch_13_automapper/Entities/Exceptions/BookNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public sealed class BookNotFoundException : NotFoundException 3 | { 4 | public BookNotFoundException(int id) : base($"The book with {id} could not be found!") 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_13_automapper/Entities/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | namespace Entities.Exceptions; 3 | public class ErrorDetails 4 | { 5 | public int StatusCode { get; set; } 6 | public String? Message { get; set; } 7 | public String? AtOccured => DateTime.Now.ToLongDateString(); 8 | 9 | public override string ToString() 10 | { 11 | return JsonSerializer.Serialize(this); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch_13_automapper/Entities/Exceptions/NotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public abstract class NotFoundException : Exception 3 | { 4 | protected NotFoundException(string message) : base(message) 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_13_automapper/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:44417", 8 | "sslPort": 44371 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5202", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7141;http://localhost:5202", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_13_automapper/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | 3 | namespace Repositories; 4 | 5 | public class BookRepository 6 | { 7 | private readonly RepositoryContext _context; 8 | 9 | public BookRepository(RepositoryContext context) 10 | { 11 | _context = context; 12 | } 13 | 14 | public Book? Get(int id) => 15 | _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 16 | 17 | public List GetAll() => 18 | _context.Books.ToList(); 19 | 20 | public void Add(Book item) 21 | { 22 | _context.Books.Add(item); 23 | _context.SaveChanges(); 24 | } 25 | public void Remove(Book item) 26 | { 27 | _context.Remove(item); 28 | _context.SaveChanges(); 29 | } 30 | public void Update(Book item) 31 | { 32 | _context.Books.Update(item); 33 | _context.SaveChanges(); 34 | } 35 | } -------------------------------------------------------------------------------- /ch_13_automapper/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class RepositoryContext : DbContext 7 | { 8 | public DbSet Books { get; set; } 9 | public RepositoryContext(DbContextOptions options) 10 | : base(options) 11 | { 12 | 13 | } 14 | 15 | protected override void OnModelCreating(ModelBuilder modelBuilder) 16 | { 17 | base.OnModelCreating(modelBuilder); 18 | modelBuilder.Entity().HasData( 19 | new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 20 | new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 21 | new Book { Id = 3, Title = "Huzur", Price = 18.75M } 22 | ); 23 | } 24 | } -------------------------------------------------------------------------------- /ch_13_automapper/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | 5 | // namespace Services; 6 | 7 | // public class BookService : IBookService 8 | // { 9 | // private readonly List _bookList; 10 | // public BookService() 11 | // { 12 | // // seed data 13 | // _bookList = new List() 14 | // { 15 | // new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 16 | // new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 17 | // new Book { Id = 3, Title = "Huzur", Price = 18.75M } 18 | // }; 19 | // } 20 | 21 | // public List GetBooks() => _bookList; 22 | 23 | // public int Count => _bookList.Count; 24 | 25 | // public Book? GetBookById(int id) => 26 | // _bookList.FirstOrDefault(b => b.Id.Equals(id)); 27 | 28 | // public void AddBook(Book newBook) 29 | // { 30 | // newBook.Id = _bookList.Max(b => b.Id) + 1; 31 | // _bookList.Add(newBook); 32 | // } 33 | 34 | // public Book UpdateBook(int id, Book updateBook) 35 | // { 36 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 37 | // if (book is null) 38 | // { 39 | // throw new BookNotFoundException(id); 40 | // } 41 | 42 | // book.Title = updateBook.Title; 43 | // book.Price = updateBook.Price; 44 | 45 | // return book; 46 | // } 47 | 48 | // public void DeleteBook(int id) 49 | // { 50 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 51 | // if (book is not null) 52 | // { 53 | // _bookList.Remove(book); 54 | // } 55 | // else 56 | // { 57 | // throw new BookNotFoundException(id); 58 | // } 59 | // } 60 | // } -------------------------------------------------------------------------------- /ch_13_automapper/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | // using Repositories; 5 | 6 | // namespace Services; 7 | 8 | // public class BookServiceV2 : IBookService 9 | // { 10 | // private readonly RepositoryContext _context; 11 | 12 | // public BookServiceV2(RepositoryContext context) 13 | // { 14 | // _context = context; 15 | // } 16 | 17 | // public int Count => _context.Books.ToList().Count; 18 | 19 | // public void AddBook(Book item) 20 | // { 21 | // _context.Books.Add(item); 22 | // _context.SaveChanges(); 23 | // } 24 | 25 | // public void DeleteBook(int id) 26 | // { 27 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 28 | // if (book is not null) 29 | // { 30 | // _context.Books.Remove(book); 31 | // _context.SaveChanges(); 32 | // } 33 | // else 34 | // { 35 | // throw new BookNotFoundException(id); 36 | // } 37 | // } 38 | 39 | // public Book? GetBookById(int id) => 40 | // _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 41 | 42 | // public List GetBooks() => 43 | // _context.Books.ToList(); 44 | 45 | 46 | // public Book UpdateBook(int id, Book item) 47 | // { 48 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 49 | // if (book is null) 50 | // { 51 | // throw new BookNotFoundException(id); 52 | // } 53 | 54 | // book.Title = item.Title; 55 | // book.Price = item.Price; 56 | // _context.SaveChanges(); 57 | // return book; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /ch_13_automapper/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Abstracts; 3 | using AutoMapper; 4 | using Configuration; 5 | using Entities; 6 | using Entities.DTOs; 7 | using Entities.Exceptions; 8 | using Repositories; 9 | 10 | namespace Services; 11 | 12 | public class BookServiceV3 : IBookService 13 | { 14 | private readonly BookRepository _bookRepo; 15 | private readonly IMapper _mapper; 16 | 17 | public BookServiceV3(BookRepository bookRepo, IMapper mapper) 18 | { 19 | _bookRepo = bookRepo; 20 | _mapper = mapper; 21 | } 22 | 23 | public int Count => _bookRepo.GetAll().Count; 24 | 25 | public Book AddBook(BookDtoForInsertion item) 26 | { 27 | var validationResults = new List(); 28 | var context = new ValidationContext(item); 29 | var isValid = Validator 30 | .TryValidateObject(item, context, validationResults, true); 31 | 32 | if (!isValid) 33 | { 34 | var errors = string.Join(" ", validationResults.Select(v => v.ErrorMessage)); 35 | throw new ValidationException(errors); 36 | } 37 | 38 | var book = _mapper.Map(item); 39 | _bookRepo.Add(book); 40 | return book; 41 | } 42 | 43 | public void DeleteBook(int id) 44 | { 45 | id.VadaliteIdInRange(); 46 | 47 | var book = _bookRepo.Get(id); 48 | if (book is not null) 49 | _bookRepo.Remove(book); 50 | else 51 | throw new BookNotFoundException(id); 52 | } 53 | 54 | public Book? GetBookById(int id) 55 | { 56 | id.VadaliteIdInRange(); 57 | var book = _bookRepo.Get(id); 58 | if (book is null) 59 | { 60 | throw new BookNotFoundException(id); 61 | } 62 | return book; 63 | } 64 | 65 | 66 | public List GetBooks() => 67 | _bookRepo.GetAll(); 68 | 69 | 70 | public Book UpdateBook(int id, BookDtoForUpdate item) 71 | { 72 | id.VadaliteIdInRange(); 73 | 74 | var validationResults = new List(); 75 | var context = new ValidationContext(item); 76 | var isValid = Validator 77 | .TryValidateObject(item, context, validationResults, true); 78 | 79 | if (!isValid) 80 | { 81 | var errors = string.Join(" ", 82 | validationResults.Select(v => v.ErrorMessage)); 83 | 84 | throw new ValidationException(errors); 85 | } 86 | 87 | var book = GetBookById(id); 88 | book = _mapper.Map(item, book); 89 | _bookRepo.Update(book); 90 | return book; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ch_13_automapper/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_13_automapper/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | } 12 | } -------------------------------------------------------------------------------- /ch_13_automapper/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_13_automapper/database.db -------------------------------------------------------------------------------- /ch_14_relations/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Entities.DTOs; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IBookService 7 | { 8 | int Count { get; } 9 | List GetBooks(); 10 | BookDto? GetBookById(int id); 11 | Book AddBook(BookDtoForInsertion item); 12 | Book UpdateBook(int id, BookDtoForUpdate item); 13 | void DeleteBook(int id); 14 | } 15 | -------------------------------------------------------------------------------- /ch_14_relations/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch_14_relations/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5202 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_14_relations/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookApi", "BookApi.csproj", "{565B12F3-B124-41A2-AC83-5028715780A1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ch_14_relations/Configuration/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Entities; 3 | using Entities.DTOs; 4 | 5 | namespace Configuration; 6 | 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap().ReverseMap(); 12 | CreateMap().ReverseMap(); 13 | CreateMap().ReverseMap(); 14 | } 15 | } -------------------------------------------------------------------------------- /ch_14_relations/Entities/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Collections.Generic; 4 | 5 | namespace Entities; 6 | 7 | public class Book 8 | { 9 | public int Id { get; set; } 10 | 11 | public String? Title { get; set; } 12 | public Decimal Price { get; set; } 13 | public String? URL { get; set; } 14 | 15 | public int CategoryId { get; set; } 16 | public Category? Category { get; set; } // navigation property 17 | public Book() 18 | { 19 | URL = "/images/default.jpg"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Entities; 4 | 5 | public class Category 6 | { 7 | public int CategoryId { get; set; } 8 | public String? CategoryName { get; set; } 9 | 10 | [JsonIgnore] 11 | public ICollection? Books { get; set; } // collection navigation property 12 | } -------------------------------------------------------------------------------- /ch_14_relations/Entities/DTOs/BookDto.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.DTOs; 2 | 3 | 4 | public record BookDto : BookDtoBase 5 | { 6 | public int Id { get; init; } 7 | public Category Category { get; init; } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/DTOs/BookDtoBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public abstract record BookDtoBase 6 | { 7 | [MinLength(2, ErrorMessage = "The title should include at least two characters.")] 8 | [MaxLength(25, ErrorMessage = "The title must be 25 characters or less.")] 9 | public String Title { get; init; } 10 | 11 | [Range(1, 100, ErrorMessage = "Price must be between 1 and 100.")] 12 | public Decimal Price { get; init; } 13 | 14 | [Required(ErrorMessage = "Category ID is required.")] 15 | public int CategoryId { get; init; } 16 | } 17 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/DTOs/BookDtoForInsertion.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForInsertion : BookDtoBase 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/DTOs/BookDtoForUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForUpdate : BookDtoBase 6 | { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/Exceptions/BookNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public sealed class BookNotFoundException : NotFoundException 3 | { 4 | public BookNotFoundException(int id) : base($"The book with {id} could not be found!") 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | namespace Entities.Exceptions; 3 | public class ErrorDetails 4 | { 5 | public int StatusCode { get; set; } 6 | public String? Message { get; set; } 7 | public String? AtOccured => DateTime.Now.ToLongDateString(); 8 | 9 | public override string ToString() 10 | { 11 | return JsonSerializer.Serialize(this); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch_14_relations/Entities/Exceptions/NotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public abstract class NotFoundException : Exception 3 | { 4 | protected NotFoundException(string message) : base(message) 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_14_relations/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:44417", 8 | "sslPort": 44371 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5202", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7141;http://localhost:5202", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_14_relations/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class BookRepository : RepositoryBase 7 | { 8 | public BookRepository(RepositoryContext context) : base(context) 9 | { 10 | 11 | } 12 | 13 | public override Book? Get(int id) => 14 | _context 15 | .Books 16 | .Include(b => b.Category) // eager loading 17 | .FirstOrDefault(b => b.Id.Equals(id)); 18 | 19 | public override List GetAll() => 20 | _context 21 | .Books 22 | .Include(b => b.Category) // eager loading 23 | .ToList(); 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch_14_relations/Repositories/CategoryRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | 3 | namespace Repositories; 4 | 5 | public class CategoryRepository : RepositoryBase 6 | { 7 | public CategoryRepository(RepositoryContext context) : base(context) 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /ch_14_relations/Repositories/RepositoryBase.cs: -------------------------------------------------------------------------------- 1 | namespace Repositories; 2 | 3 | public abstract class RepositoryBase 4 | where T:class, new() 5 | { 6 | protected readonly RepositoryContext _context; 7 | 8 | protected RepositoryBase(RepositoryContext context) 9 | { 10 | _context = context; 11 | } 12 | 13 | public virtual T? Get(int id) => 14 | _context 15 | .Set() 16 | .Find(id); 17 | 18 | public virtual List GetAll() => 19 | _context 20 | .Set() 21 | .ToList(); 22 | 23 | public virtual void Add(T item) 24 | { 25 | _context 26 | .Set() 27 | .Add(item); 28 | _context.SaveChanges(); 29 | } 30 | 31 | public virtual void Remove(T item) 32 | { 33 | _context 34 | .Set() 35 | .Remove(item); 36 | _context.SaveChanges(); 37 | } 38 | 39 | public virtual void Update(T item) 40 | { 41 | _context 42 | .Set() 43 | .Update(item); 44 | _context.SaveChanges(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch_14_relations/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class RepositoryContext : DbContext 7 | { 8 | public DbSet Books { get; set; } 9 | public DbSet Categories { get; set; } 10 | 11 | public RepositoryContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | 15 | } 16 | 17 | protected override void OnModelCreating(ModelBuilder modelBuilder) 18 | { 19 | base.OnModelCreating(modelBuilder); 20 | 21 | // Seed the Category entities first 22 | modelBuilder.Entity().HasData( 23 | new Category 24 | { 25 | CategoryId = 1, 26 | CategoryName = "Felsefe" 27 | }, 28 | new Category 29 | { 30 | CategoryId = 2, 31 | CategoryName = "Roman" 32 | }, 33 | new Category 34 | { 35 | CategoryId = 3, 36 | CategoryName = "Deneme" 37 | } 38 | ); 39 | 40 | // Seed the Book entities and reference the categories using CategoryId 41 | modelBuilder.Entity().HasData( 42 | new Book 43 | { 44 | Id = 1, 45 | Title = "Devlet", 46 | Price = 20.00M, 47 | URL = "/images/1.jpg", 48 | CategoryId = 1 49 | }, 50 | new Book 51 | { 52 | Id = 2, 53 | Title = "Ateşten Gömlek", 54 | Price = 15.50M, 55 | URL = "/images/1.jpg", 56 | CategoryId = 2 57 | }, 58 | new Book 59 | { 60 | Id = 3, 61 | Title = "Huzur", 62 | Price = 18.75M, 63 | URL = "/images/1.jpg", 64 | CategoryId = 3 65 | } 66 | ); 67 | } 68 | } -------------------------------------------------------------------------------- /ch_14_relations/Services/AuthorService.cs: -------------------------------------------------------------------------------- 1 | // Author Servis gelecek -------------------------------------------------------------------------------- /ch_14_relations/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | 5 | // namespace Services; 6 | 7 | // public class BookService : IBookService 8 | // { 9 | // private readonly List _bookList; 10 | // public BookService() 11 | // { 12 | // // seed data 13 | // _bookList = new List() 14 | // { 15 | // new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 16 | // new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 17 | // new Book { Id = 3, Title = "Huzur", Price = 18.75M } 18 | // }; 19 | // } 20 | 21 | // public List GetBooks() => _bookList; 22 | 23 | // public int Count => _bookList.Count; 24 | 25 | // public Book? GetBookById(int id) => 26 | // _bookList.FirstOrDefault(b => b.Id.Equals(id)); 27 | 28 | // public void AddBook(Book newBook) 29 | // { 30 | // newBook.Id = _bookList.Max(b => b.Id) + 1; 31 | // _bookList.Add(newBook); 32 | // } 33 | 34 | // public Book UpdateBook(int id, Book updateBook) 35 | // { 36 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 37 | // if (book is null) 38 | // { 39 | // throw new BookNotFoundException(id); 40 | // } 41 | 42 | // book.Title = updateBook.Title; 43 | // book.Price = updateBook.Price; 44 | 45 | // return book; 46 | // } 47 | 48 | // public void DeleteBook(int id) 49 | // { 50 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 51 | // if (book is not null) 52 | // { 53 | // _bookList.Remove(book); 54 | // } 55 | // else 56 | // { 57 | // throw new BookNotFoundException(id); 58 | // } 59 | // } 60 | // } -------------------------------------------------------------------------------- /ch_14_relations/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | // using Repositories; 5 | 6 | // namespace Services; 7 | 8 | // public class BookServiceV2 : IBookService 9 | // { 10 | // private readonly RepositoryContext _context; 11 | 12 | // public BookServiceV2(RepositoryContext context) 13 | // { 14 | // _context = context; 15 | // } 16 | 17 | // public int Count => _context.Books.ToList().Count; 18 | 19 | // public void AddBook(Book item) 20 | // { 21 | // _context.Books.Add(item); 22 | // _context.SaveChanges(); 23 | // } 24 | 25 | // public void DeleteBook(int id) 26 | // { 27 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 28 | // if (book is not null) 29 | // { 30 | // _context.Books.Remove(book); 31 | // _context.SaveChanges(); 32 | // } 33 | // else 34 | // { 35 | // throw new BookNotFoundException(id); 36 | // } 37 | // } 38 | 39 | // public Book? GetBookById(int id) => 40 | // _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 41 | 42 | // public List GetBooks() => 43 | // _context.Books.ToList(); 44 | 45 | 46 | // public Book UpdateBook(int id, Book item) 47 | // { 48 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 49 | // if (book is null) 50 | // { 51 | // throw new BookNotFoundException(id); 52 | // } 53 | 54 | // book.Title = item.Title; 55 | // book.Price = item.Price; 56 | // _context.SaveChanges(); 57 | // return book; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /ch_14_relations/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Abstracts; 3 | using AutoMapper; 4 | using Configuration; 5 | using Entities; 6 | using Entities.DTOs; 7 | using Entities.Exceptions; 8 | using Repositories; 9 | 10 | namespace Services; 11 | 12 | public class BookServiceV3 : IBookService 13 | { 14 | private readonly BookRepository _bookRepo; 15 | private readonly IMapper _mapper; 16 | 17 | public BookServiceV3(BookRepository bookRepo, IMapper mapper) 18 | { 19 | _bookRepo = bookRepo; 20 | _mapper = mapper; 21 | } 22 | 23 | public int Count => _bookRepo.GetAll().Count; 24 | 25 | public Book AddBook(BookDtoForInsertion item) 26 | { 27 | Validate(item); 28 | var book = _mapper.Map(item); 29 | _bookRepo.Add(book); 30 | return book; 31 | } 32 | 33 | public void DeleteBook(int id) 34 | { 35 | id.VadaliteIdInRange(); 36 | 37 | var book = _bookRepo.Get(id); 38 | if (book is not null) 39 | _bookRepo.Remove(book); 40 | else 41 | throw new BookNotFoundException(id); 42 | } 43 | 44 | public BookDto? GetBookById(int id) 45 | { 46 | id.VadaliteIdInRange(); 47 | 48 | var book = _bookRepo.Get(id); 49 | 50 | if (book is null) 51 | { 52 | throw new BookNotFoundException(id); 53 | } 54 | return _mapper.Map(book); 55 | } 56 | 57 | 58 | public List GetBooks() 59 | { 60 | var books = _bookRepo.GetAll(); 61 | return _mapper.Map>(books); 62 | } 63 | 64 | public Book UpdateBook(int id, BookDtoForUpdate item) 65 | { 66 | id.VadaliteIdInRange(); 67 | Validate(item); 68 | var book = _bookRepo.Get(id); 69 | if (book is null) 70 | { 71 | throw new BookNotFoundException(id); 72 | } 73 | _mapper.Map(item, book); 74 | _bookRepo.Update(book); 75 | return book; 76 | } 77 | 78 | 79 | 80 | private void Validate(T item) 81 | { 82 | var validationResults = new List(); 83 | var context = new ValidationContext(item); 84 | var isValid = Validator.TryValidateObject(item, context, validationResults, true); 85 | 86 | if(!isValid) 87 | { 88 | var errors = string.Join(" ", validationResults.Select(v => v.ErrorMessage)); 89 | throw new ValidationException(errors); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ch_14_relations/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_14_relations/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | } 12 | } -------------------------------------------------------------------------------- /ch_14_relations/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_14_relations/database.db -------------------------------------------------------------------------------- /ch_15_auth/Abstracts/IAuthService.cs: -------------------------------------------------------------------------------- 1 | using Entities.DTOs; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IAuthService 7 | { 8 | Task RegisterUserAsync(UserForRegistrationDto userDto); 9 | } 10 | -------------------------------------------------------------------------------- /ch_15_auth/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Entities.DTOs; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IBookService 7 | { 8 | int Count { get; } 9 | List GetBooks(); 10 | BookDto? GetBookById(int id); 11 | Book AddBook(BookDtoForInsertion item); 12 | Book UpdateBook(int id, BookDtoForUpdate item); 13 | void DeleteBook(int id); 14 | } 15 | -------------------------------------------------------------------------------- /ch_15_auth/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | all 17 | 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ch_15_auth/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5202 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_15_auth/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookApi", "BookApi.csproj", "{565B12F3-B124-41A2-AC83-5028715780A1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ch_15_auth/Configuration/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Entities; 3 | using Entities.DTOs; 4 | 5 | namespace Configuration; 6 | 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap().ReverseMap(); 12 | CreateMap().ReverseMap(); 13 | CreateMap().ReverseMap(); 14 | CreateMap().ReverseMap(); 15 | } 16 | } -------------------------------------------------------------------------------- /ch_15_auth/Entities/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Collections.Generic; 4 | 5 | namespace Entities; 6 | 7 | public class Book 8 | { 9 | public int Id { get; set; } 10 | 11 | public String? Title { get; set; } 12 | public Decimal Price { get; set; } 13 | public String? URL { get; set; } 14 | 15 | public int CategoryId { get; set; } 16 | public Category? Category { get; set; } // navigation property 17 | public Book() 18 | { 19 | URL = "/images/default.jpg"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Entities; 4 | 5 | public class Category 6 | { 7 | public int CategoryId { get; set; } 8 | public String? CategoryName { get; set; } 9 | 10 | [JsonIgnore] 11 | public ICollection? Books { get; set; } // collection navigation property 12 | } -------------------------------------------------------------------------------- /ch_15_auth/Entities/DTOs/BookDto.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.DTOs; 2 | 3 | public record BookDto : BookDtoBase 4 | { 5 | public int Id { get; init; } 6 | public Category Category { get; init; } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/DTOs/BookDtoBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public abstract record BookDtoBase 6 | { 7 | [MinLength(2, ErrorMessage = "The title should include at least two characters.")] 8 | [MaxLength(25, ErrorMessage = "The title must be 25 characters or less.")] 9 | public String Title { get; init; } 10 | 11 | [Range(1, 100, ErrorMessage = "Price must be between 1 and 100.")] 12 | public Decimal Price { get; init; } 13 | 14 | [Required(ErrorMessage = "Category ID is required.")] 15 | public int CategoryId { get; init; } 16 | } 17 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/DTOs/BookDtoForInsertion.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForInsertion : BookDtoBase 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/DTOs/BookDtoForUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForUpdate : BookDtoBase 6 | { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/DTOs/UserForRegistrationDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record UserForRegistrationDto 6 | { 7 | public String? FirstName { get; init; } 8 | public String? LastName { get; init; } 9 | 10 | [Required(ErrorMessage = "Username is required!")] 11 | public String UserName { get; init; } 12 | 13 | [Required(ErrorMessage = "Password is required!")] 14 | public String Password { get; init; } 15 | 16 | public String? Email { get; init; } 17 | public String? PhoneNumber { get; init; } 18 | public ICollection? Roles { get; init; } 19 | } 20 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/Exceptions/BookNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public sealed class BookNotFoundException : NotFoundException 3 | { 4 | public BookNotFoundException(int id) : base($"The book with {id} could not be found!") 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | namespace Entities.Exceptions; 3 | public class ErrorDetails 4 | { 5 | public int StatusCode { get; set; } 6 | public String? Message { get; set; } 7 | public String? AtOccured => DateTime.Now.ToLongDateString(); 8 | 9 | public override string ToString() 10 | { 11 | return JsonSerializer.Serialize(this); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/Exceptions/NotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public abstract class NotFoundException : Exception 3 | { 4 | protected NotFoundException(string message) : base(message) 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_15_auth/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | 3 | namespace Entities; 4 | 5 | public class User : IdentityUser 6 | { 7 | public String? FirstName { get; set; } 8 | public String? LastName { get; set; } 9 | } -------------------------------------------------------------------------------- /ch_15_auth/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:44417", 8 | "sslPort": 44371 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5202", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7141;http://localhost:5202", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_15_auth/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class BookRepository : RepositoryBase 7 | { 8 | public BookRepository(RepositoryContext context) : base(context) 9 | { 10 | 11 | } 12 | 13 | public override Book? Get(int id) => 14 | _context 15 | .Books 16 | .Include(b => b.Category) // eager loading 17 | .FirstOrDefault(b => b.Id.Equals(id)); 18 | 19 | public override List GetAll() => 20 | _context 21 | .Books 22 | .Include(b => b.Category) // eager loading 23 | .ToList(); 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch_15_auth/Repositories/CategoryRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | 3 | namespace Repositories; 4 | 5 | public class CategoryRepository : RepositoryBase 6 | { 7 | public CategoryRepository(RepositoryContext context) : base(context) 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /ch_15_auth/Repositories/RepositoryBase.cs: -------------------------------------------------------------------------------- 1 | namespace Repositories; 2 | 3 | public abstract class RepositoryBase 4 | where T:class, new() 5 | { 6 | protected readonly RepositoryContext _context; 7 | 8 | protected RepositoryBase(RepositoryContext context) 9 | { 10 | _context = context; 11 | } 12 | 13 | public virtual T? Get(int id) => 14 | _context 15 | .Set() 16 | .Find(id); 17 | 18 | public virtual List GetAll() => 19 | _context 20 | .Set() 21 | .ToList(); 22 | 23 | public virtual void Add(T item) 24 | { 25 | _context 26 | .Set() 27 | .Add(item); 28 | _context.SaveChanges(); 29 | } 30 | 31 | public virtual void Remove(T item) 32 | { 33 | _context 34 | .Set() 35 | .Remove(item); 36 | _context.SaveChanges(); 37 | } 38 | 39 | public virtual void Update(T item) 40 | { 41 | _context 42 | .Set() 43 | .Update(item); 44 | _context.SaveChanges(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch_15_auth/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Repositories; 7 | 8 | public class RepositoryContext : IdentityDbContext 9 | { 10 | public DbSet Books { get; set; } 11 | public DbSet Categories { get; set; } 12 | 13 | public RepositoryContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | base.OnModelCreating(modelBuilder); 22 | 23 | // Seed the Category entities first 24 | modelBuilder.Entity().HasData( 25 | new Category 26 | { 27 | CategoryId = 1, 28 | CategoryName = "Felsefe" 29 | }, 30 | new Category 31 | { 32 | CategoryId = 2, 33 | CategoryName = "Roman" 34 | }, 35 | new Category 36 | { 37 | CategoryId = 3, 38 | CategoryName = "Deneme" 39 | } 40 | ); 41 | 42 | // Seed the Book entities and reference the categories using CategoryId 43 | modelBuilder.Entity().HasData( 44 | new Book 45 | { 46 | Id = 1, 47 | Title = "Devlet", 48 | Price = 20.00M, 49 | URL = "/images/1.jpg", 50 | CategoryId = 1 51 | }, 52 | new Book 53 | { 54 | Id = 2, 55 | Title = "Ateşten Gömlek", 56 | Price = 15.50M, 57 | URL = "/images/1.jpg", 58 | CategoryId = 2 59 | }, 60 | new Book 61 | { 62 | Id = 3, 63 | Title = "Huzur", 64 | Price = 18.75M, 65 | URL = "/images/1.jpg", 66 | CategoryId = 3 67 | } 68 | ); 69 | 70 | // Seed the Role data 71 | modelBuilder.Entity().HasData( 72 | new IdentityRole 73 | { 74 | Name = "Admin", 75 | NormalizedName = "ADMIN" 76 | }, 77 | new IdentityRole 78 | { 79 | Name = "User", 80 | NormalizedName = "USER" 81 | } 82 | ); 83 | } 84 | } -------------------------------------------------------------------------------- /ch_15_auth/Services/AuthenticationManager.cs: -------------------------------------------------------------------------------- 1 | using Abstracts; 2 | using AutoMapper; 3 | using Entities; 4 | using Entities.DTOs; 5 | using Microsoft.AspNetCore.Identity; 6 | 7 | namespace Services; 8 | 9 | public class AuthenticationManager : IAuthService 10 | { 11 | private readonly IMapper _mapper; 12 | private readonly UserManager _userManager; 13 | 14 | public AuthenticationManager(IMapper mapper, 15 | UserManager userManager) 16 | { 17 | _mapper = mapper; 18 | _userManager = userManager; 19 | } 20 | 21 | public async Task RegisterUserAsync(UserForRegistrationDto userDto) 22 | { 23 | var user = _mapper.Map(userDto); 24 | 25 | var result = await _userManager 26 | .CreateAsync(user, userDto.Password); 27 | 28 | if(result.Succeeded) 29 | { 30 | await _userManager.AddToRolesAsync(user, userDto.Roles); 31 | } 32 | return result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch_15_auth/Services/AuthorService.cs: -------------------------------------------------------------------------------- 1 | // Author Servis gelecek -------------------------------------------------------------------------------- /ch_15_auth/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | 5 | // namespace Services; 6 | 7 | // public class BookService : IBookService 8 | // { 9 | // private readonly List _bookList; 10 | // public BookService() 11 | // { 12 | // // seed data 13 | // _bookList = new List() 14 | // { 15 | // new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 16 | // new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 17 | // new Book { Id = 3, Title = "Huzur", Price = 18.75M } 18 | // }; 19 | // } 20 | 21 | // public List GetBooks() => _bookList; 22 | 23 | // public int Count => _bookList.Count; 24 | 25 | // public Book? GetBookById(int id) => 26 | // _bookList.FirstOrDefault(b => b.Id.Equals(id)); 27 | 28 | // public void AddBook(Book newBook) 29 | // { 30 | // newBook.Id = _bookList.Max(b => b.Id) + 1; 31 | // _bookList.Add(newBook); 32 | // } 33 | 34 | // public Book UpdateBook(int id, Book updateBook) 35 | // { 36 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 37 | // if (book is null) 38 | // { 39 | // throw new BookNotFoundException(id); 40 | // } 41 | 42 | // book.Title = updateBook.Title; 43 | // book.Price = updateBook.Price; 44 | 45 | // return book; 46 | // } 47 | 48 | // public void DeleteBook(int id) 49 | // { 50 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 51 | // if (book is not null) 52 | // { 53 | // _bookList.Remove(book); 54 | // } 55 | // else 56 | // { 57 | // throw new BookNotFoundException(id); 58 | // } 59 | // } 60 | // } -------------------------------------------------------------------------------- /ch_15_auth/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | // using Repositories; 5 | 6 | // namespace Services; 7 | 8 | // public class BookServiceV2 : IBookService 9 | // { 10 | // private readonly RepositoryContext _context; 11 | 12 | // public BookServiceV2(RepositoryContext context) 13 | // { 14 | // _context = context; 15 | // } 16 | 17 | // public int Count => _context.Books.ToList().Count; 18 | 19 | // public void AddBook(Book item) 20 | // { 21 | // _context.Books.Add(item); 22 | // _context.SaveChanges(); 23 | // } 24 | 25 | // public void DeleteBook(int id) 26 | // { 27 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 28 | // if (book is not null) 29 | // { 30 | // _context.Books.Remove(book); 31 | // _context.SaveChanges(); 32 | // } 33 | // else 34 | // { 35 | // throw new BookNotFoundException(id); 36 | // } 37 | // } 38 | 39 | // public Book? GetBookById(int id) => 40 | // _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 41 | 42 | // public List GetBooks() => 43 | // _context.Books.ToList(); 44 | 45 | 46 | // public Book UpdateBook(int id, Book item) 47 | // { 48 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 49 | // if (book is null) 50 | // { 51 | // throw new BookNotFoundException(id); 52 | // } 53 | 54 | // book.Title = item.Title; 55 | // book.Price = item.Price; 56 | // _context.SaveChanges(); 57 | // return book; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /ch_15_auth/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Abstracts; 3 | using AutoMapper; 4 | using Configuration; 5 | using Entities; 6 | using Entities.DTOs; 7 | using Entities.Exceptions; 8 | using Repositories; 9 | 10 | namespace Services; 11 | 12 | public class BookServiceV3 : IBookService 13 | { 14 | private readonly BookRepository _bookRepo; 15 | private readonly IMapper _mapper; 16 | 17 | public BookServiceV3(BookRepository bookRepo, IMapper mapper) 18 | { 19 | _bookRepo = bookRepo; 20 | _mapper = mapper; 21 | } 22 | 23 | public int Count => _bookRepo.GetAll().Count; 24 | 25 | public Book AddBook(BookDtoForInsertion item) 26 | { 27 | Validate(item); 28 | var book = _mapper.Map(item); 29 | _bookRepo.Add(book); 30 | return book; 31 | } 32 | 33 | public void DeleteBook(int id) 34 | { 35 | id.VadaliteIdInRange(); 36 | 37 | var book = _bookRepo.Get(id); 38 | if (book is not null) 39 | _bookRepo.Remove(book); 40 | else 41 | throw new BookNotFoundException(id); 42 | } 43 | 44 | public BookDto? GetBookById(int id) 45 | { 46 | id.VadaliteIdInRange(); 47 | 48 | var book = _bookRepo.Get(id); 49 | 50 | if (book is null) 51 | { 52 | throw new BookNotFoundException(id); 53 | } 54 | return _mapper.Map(book); 55 | } 56 | 57 | 58 | public List GetBooks() 59 | { 60 | var books = _bookRepo.GetAll(); 61 | return _mapper.Map>(books); 62 | } 63 | 64 | public Book UpdateBook(int id, BookDtoForUpdate item) 65 | { 66 | id.VadaliteIdInRange(); 67 | Validate(item); 68 | var book = _bookRepo.Get(id); 69 | if (book is null) 70 | { 71 | throw new BookNotFoundException(id); 72 | } 73 | _mapper.Map(item, book); 74 | _bookRepo.Update(book); 75 | return book; 76 | } 77 | 78 | 79 | 80 | private void Validate(T item) 81 | { 82 | var validationResults = new List(); 83 | var context = new ValidationContext(item); 84 | var isValid = Validator.TryValidateObject(item, context, validationResults, true); 85 | 86 | if(!isValid) 87 | { 88 | var errors = string.Join(" ", validationResults.Select(v => v.ErrorMessage)); 89 | throw new ValidationException(errors); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ch_15_auth/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_15_auth/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | } 12 | } -------------------------------------------------------------------------------- /ch_15_auth/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_15_auth/database.db -------------------------------------------------------------------------------- /ch_16_jwt/Abstracts/IAuthService.cs: -------------------------------------------------------------------------------- 1 | using Entities.DTOs; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IAuthService 7 | { 8 | Task RegisterUserAsync(UserForRegistrationDto userDto); 9 | Task ValidateUserAsync(UserForAuthenticationDto userDto); 10 | Task CreateTokenAsync(); 11 | } 12 | -------------------------------------------------------------------------------- /ch_16_jwt/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Entities.DTOs; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IBookService 7 | { 8 | int Count { get; } 9 | List GetBooks(); 10 | BookDto? GetBookById(int id); 11 | Book AddBook(BookDtoForInsertion item); 12 | Book UpdateBook(int id, BookDtoForUpdate item); 13 | void DeleteBook(int id); 14 | } 15 | -------------------------------------------------------------------------------- /ch_16_jwt/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | all 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ch_16_jwt/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5202 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_16_jwt/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookApi", "BookApi.csproj", "{565B12F3-B124-41A2-AC83-5028715780A1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ch_16_jwt/Configuration/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Entities; 3 | using Entities.DTOs; 4 | 5 | namespace Configuration; 6 | 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap().ReverseMap(); 12 | CreateMap().ReverseMap(); 13 | CreateMap().ReverseMap(); 14 | CreateMap().ReverseMap(); 15 | CreateMap().ReverseMap(); 16 | } 17 | } -------------------------------------------------------------------------------- /ch_16_jwt/Entities/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Collections.Generic; 4 | 5 | namespace Entities; 6 | 7 | public class Book 8 | { 9 | public int Id { get; set; } 10 | 11 | public String? Title { get; set; } 12 | public Decimal Price { get; set; } 13 | public String? URL { get; set; } 14 | 15 | public int CategoryId { get; set; } 16 | public Category? Category { get; set; } // navigation property 17 | public Book() 18 | { 19 | URL = "/images/default.jpg"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Entities; 4 | 5 | public class Category 6 | { 7 | public int CategoryId { get; set; } 8 | public String? CategoryName { get; set; } 9 | 10 | [JsonIgnore] 11 | public ICollection? Books { get; set; } // collection navigation property 12 | } -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/BookDto.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.DTOs; 2 | 3 | public record BookDto : BookDtoBase 4 | { 5 | public int Id { get; init; } 6 | public Category Category { get; init; } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/BookDtoBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public abstract record BookDtoBase 6 | { 7 | [MinLength(2, ErrorMessage = "The title should include at least two characters.")] 8 | [MaxLength(25, ErrorMessage = "The title must be 25 characters or less.")] 9 | public String Title { get; init; } 10 | 11 | [Range(1, 100, ErrorMessage = "Price must be between 1 and 100.")] 12 | public Decimal Price { get; init; } 13 | 14 | [Required(ErrorMessage = "Category ID is required.")] 15 | public int CategoryId { get; init; } 16 | } 17 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/BookDtoForInsertion.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForInsertion : BookDtoBase 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/BookDtoForUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForUpdate : BookDtoBase 6 | { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/UserForAuthenticationDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record UserForAuthenticationDto 6 | { 7 | [Required(ErrorMessage = "Username is required!")] 8 | public String UserName { get; init; } 9 | 10 | [Required(ErrorMessage = "Password is required!")] 11 | public String Password { get; init; } 12 | } 13 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/DTOs/UserForRegistrationDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record UserForRegistrationDto 6 | { 7 | public String? FirstName { get; init; } 8 | public String? LastName { get; init; } 9 | 10 | [Required(ErrorMessage = "Username is required!")] 11 | public String UserName { get; init; } 12 | 13 | [Required(ErrorMessage = "Password is required!")] 14 | public String Password { get; init; } 15 | 16 | public String? Email { get; init; } 17 | public String? PhoneNumber { get; init; } 18 | public ICollection? Roles { get; init; } 19 | } 20 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/Exceptions/BookNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public sealed class BookNotFoundException : NotFoundException 3 | { 4 | public BookNotFoundException(int id) : base($"The book with {id} could not be found!") 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | namespace Entities.Exceptions; 3 | public class ErrorDetails 4 | { 5 | public int StatusCode { get; set; } 6 | public String? Message { get; set; } 7 | public String? AtOccured => DateTime.Now.ToLongDateString(); 8 | 9 | public override string ToString() 10 | { 11 | return JsonSerializer.Serialize(this); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/Exceptions/NotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public abstract class NotFoundException : Exception 3 | { 4 | protected NotFoundException(string message) : base(message) 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_16_jwt/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | 3 | namespace Entities; 4 | 5 | public class User : IdentityUser 6 | { 7 | public String? FirstName { get; set; } 8 | public String? LastName { get; set; } 9 | } -------------------------------------------------------------------------------- /ch_16_jwt/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:44417", 8 | "sslPort": 44371 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5202", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7141;http://localhost:5202", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_16_jwt/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class BookRepository : RepositoryBase 7 | { 8 | public BookRepository(RepositoryContext context) : base(context) 9 | { 10 | 11 | } 12 | 13 | public override Book? Get(int id) => 14 | _context 15 | .Books 16 | .Include(b => b.Category) // eager loading 17 | .FirstOrDefault(b => b.Id.Equals(id)); 18 | 19 | public override List GetAll() => 20 | _context 21 | .Books 22 | .Include(b => b.Category) // eager loading 23 | .ToList(); 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch_16_jwt/Repositories/CategoryRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | 3 | namespace Repositories; 4 | 5 | public class CategoryRepository : RepositoryBase 6 | { 7 | public CategoryRepository(RepositoryContext context) : base(context) 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /ch_16_jwt/Repositories/RepositoryBase.cs: -------------------------------------------------------------------------------- 1 | namespace Repositories; 2 | 3 | public abstract class RepositoryBase 4 | where T:class, new() 5 | { 6 | protected readonly RepositoryContext _context; 7 | 8 | protected RepositoryBase(RepositoryContext context) 9 | { 10 | _context = context; 11 | } 12 | 13 | public virtual T? Get(int id) => 14 | _context 15 | .Set() 16 | .Find(id); 17 | 18 | public virtual List GetAll() => 19 | _context 20 | .Set() 21 | .ToList(); 22 | 23 | public virtual void Add(T item) 24 | { 25 | _context 26 | .Set() 27 | .Add(item); 28 | _context.SaveChanges(); 29 | } 30 | 31 | public virtual void Remove(T item) 32 | { 33 | _context 34 | .Set() 35 | .Remove(item); 36 | _context.SaveChanges(); 37 | } 38 | 39 | public virtual void Update(T item) 40 | { 41 | _context 42 | .Set() 43 | .Update(item); 44 | _context.SaveChanges(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch_16_jwt/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Repositories; 7 | 8 | public class RepositoryContext : IdentityDbContext 9 | { 10 | public DbSet Books { get; set; } 11 | public DbSet Categories { get; set; } 12 | 13 | public RepositoryContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | base.OnModelCreating(modelBuilder); 22 | 23 | // Seed the Category entities first 24 | modelBuilder.Entity().HasData( 25 | new Category 26 | { 27 | CategoryId = 1, 28 | CategoryName = "Felsefe" 29 | }, 30 | new Category 31 | { 32 | CategoryId = 2, 33 | CategoryName = "Roman" 34 | }, 35 | new Category 36 | { 37 | CategoryId = 3, 38 | CategoryName = "Deneme" 39 | } 40 | ); 41 | 42 | // Seed the Book entities and reference the categories using CategoryId 43 | modelBuilder.Entity().HasData( 44 | new Book 45 | { 46 | Id = 1, 47 | Title = "Devlet", 48 | Price = 20.00M, 49 | URL = "/images/1.jpg", 50 | CategoryId = 1 51 | }, 52 | new Book 53 | { 54 | Id = 2, 55 | Title = "Ateşten Gömlek", 56 | Price = 15.50M, 57 | URL = "/images/1.jpg", 58 | CategoryId = 2 59 | }, 60 | new Book 61 | { 62 | Id = 3, 63 | Title = "Huzur", 64 | Price = 18.75M, 65 | URL = "/images/1.jpg", 66 | CategoryId = 3 67 | } 68 | ); 69 | 70 | // Seed the Role data 71 | modelBuilder.Entity().HasData( 72 | new IdentityRole 73 | { 74 | Name = "Admin", 75 | NormalizedName = "ADMIN" 76 | }, 77 | new IdentityRole 78 | { 79 | Name = "User", 80 | NormalizedName = "USER" 81 | } 82 | ); 83 | } 84 | } -------------------------------------------------------------------------------- /ch_16_jwt/Services/AuthorService.cs: -------------------------------------------------------------------------------- 1 | // Author Servis gelecek -------------------------------------------------------------------------------- /ch_16_jwt/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | 5 | // namespace Services; 6 | 7 | // public class BookService : IBookService 8 | // { 9 | // private readonly List _bookList; 10 | // public BookService() 11 | // { 12 | // // seed data 13 | // _bookList = new List() 14 | // { 15 | // new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 16 | // new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 17 | // new Book { Id = 3, Title = "Huzur", Price = 18.75M } 18 | // }; 19 | // } 20 | 21 | // public List GetBooks() => _bookList; 22 | 23 | // public int Count => _bookList.Count; 24 | 25 | // public Book? GetBookById(int id) => 26 | // _bookList.FirstOrDefault(b => b.Id.Equals(id)); 27 | 28 | // public void AddBook(Book newBook) 29 | // { 30 | // newBook.Id = _bookList.Max(b => b.Id) + 1; 31 | // _bookList.Add(newBook); 32 | // } 33 | 34 | // public Book UpdateBook(int id, Book updateBook) 35 | // { 36 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 37 | // if (book is null) 38 | // { 39 | // throw new BookNotFoundException(id); 40 | // } 41 | 42 | // book.Title = updateBook.Title; 43 | // book.Price = updateBook.Price; 44 | 45 | // return book; 46 | // } 47 | 48 | // public void DeleteBook(int id) 49 | // { 50 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 51 | // if (book is not null) 52 | // { 53 | // _bookList.Remove(book); 54 | // } 55 | // else 56 | // { 57 | // throw new BookNotFoundException(id); 58 | // } 59 | // } 60 | // } -------------------------------------------------------------------------------- /ch_16_jwt/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | // using Repositories; 5 | 6 | // namespace Services; 7 | 8 | // public class BookServiceV2 : IBookService 9 | // { 10 | // private readonly RepositoryContext _context; 11 | 12 | // public BookServiceV2(RepositoryContext context) 13 | // { 14 | // _context = context; 15 | // } 16 | 17 | // public int Count => _context.Books.ToList().Count; 18 | 19 | // public void AddBook(Book item) 20 | // { 21 | // _context.Books.Add(item); 22 | // _context.SaveChanges(); 23 | // } 24 | 25 | // public void DeleteBook(int id) 26 | // { 27 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 28 | // if (book is not null) 29 | // { 30 | // _context.Books.Remove(book); 31 | // _context.SaveChanges(); 32 | // } 33 | // else 34 | // { 35 | // throw new BookNotFoundException(id); 36 | // } 37 | // } 38 | 39 | // public Book? GetBookById(int id) => 40 | // _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 41 | 42 | // public List GetBooks() => 43 | // _context.Books.ToList(); 44 | 45 | 46 | // public Book UpdateBook(int id, Book item) 47 | // { 48 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 49 | // if (book is null) 50 | // { 51 | // throw new BookNotFoundException(id); 52 | // } 53 | 54 | // book.Title = item.Title; 55 | // book.Price = item.Price; 56 | // _context.SaveChanges(); 57 | // return book; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /ch_16_jwt/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Abstracts; 3 | using AutoMapper; 4 | using Configuration; 5 | using Entities; 6 | using Entities.DTOs; 7 | using Entities.Exceptions; 8 | using Repositories; 9 | 10 | namespace Services; 11 | 12 | public class BookServiceV3 : IBookService 13 | { 14 | private readonly BookRepository _bookRepo; 15 | private readonly IMapper _mapper; 16 | 17 | public BookServiceV3(BookRepository bookRepo, IMapper mapper) 18 | { 19 | _bookRepo = bookRepo; 20 | _mapper = mapper; 21 | } 22 | 23 | public int Count => _bookRepo.GetAll().Count; 24 | 25 | public Book AddBook(BookDtoForInsertion item) 26 | { 27 | Validate(item); 28 | var book = _mapper.Map(item); 29 | _bookRepo.Add(book); 30 | return book; 31 | } 32 | 33 | public void DeleteBook(int id) 34 | { 35 | id.VadaliteIdInRange(); 36 | 37 | var book = _bookRepo.Get(id); 38 | if (book is not null) 39 | _bookRepo.Remove(book); 40 | else 41 | throw new BookNotFoundException(id); 42 | } 43 | 44 | public BookDto? GetBookById(int id) 45 | { 46 | id.VadaliteIdInRange(); 47 | 48 | var book = _bookRepo.Get(id); 49 | 50 | if (book is null) 51 | { 52 | throw new BookNotFoundException(id); 53 | } 54 | return _mapper.Map(book); 55 | } 56 | 57 | 58 | public List GetBooks() 59 | { 60 | var books = _bookRepo.GetAll(); 61 | return _mapper.Map>(books); 62 | } 63 | 64 | public Book UpdateBook(int id, BookDtoForUpdate item) 65 | { 66 | id.VadaliteIdInRange(); 67 | Validate(item); 68 | var book = _bookRepo.Get(id); 69 | if (book is null) 70 | { 71 | throw new BookNotFoundException(id); 72 | } 73 | _mapper.Map(item, book); 74 | _bookRepo.Update(book); 75 | return book; 76 | } 77 | 78 | 79 | 80 | private void Validate(T item) 81 | { 82 | var validationResults = new List(); 83 | var context = new ValidationContext(item); 84 | var isValid = Validator.TryValidateObject(item, context, validationResults, true); 85 | 86 | if(!isValid) 87 | { 88 | var errors = string.Join(" ", validationResults.Select(v => v.ErrorMessage)); 89 | throw new ValidationException(errors); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ch_16_jwt/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_16_jwt/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | }, 12 | "JwtSettings":{ 13 | "validIssuer": "bookapi", 14 | "validAudience":"https://localhost:3000", 15 | "secretKey":"samsununiversitesiyazilimmuhendisligibolumusamsununiversitesiyazilimmuhendisligibolumu", 16 | "expire":60 17 | } 18 | } -------------------------------------------------------------------------------- /ch_16_jwt/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_16_jwt/database.db -------------------------------------------------------------------------------- /ch_17_refresh_token/Abstracts/IAuthService.cs: -------------------------------------------------------------------------------- 1 | using Entities.DTOs; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IAuthService 7 | { 8 | Task RegisterUserAsync(UserForRegistrationDto userDto); 9 | Task ValidateUserAsync(UserForAuthenticationDto userDto); 10 | Task CreateTokenAsync(bool populateExp); 11 | Task RefreshTokenAsync(TokenDto tokenDto); 12 | } 13 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Abstracts/IBookService.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Entities.DTOs; 3 | 4 | namespace Abstracts; 5 | 6 | public interface IBookService 7 | { 8 | int Count { get; } 9 | List GetBooks(); 10 | BookDto? GetBookById(int id); 11 | Book AddBook(BookDtoForInsertion item); 12 | Book UpdateBook(int id, BookDtoForUpdate item); 13 | void DeleteBook(int id); 14 | } 15 | -------------------------------------------------------------------------------- /ch_17_refresh_token/BookApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | all 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ch_17_refresh_token/BookApi.http: -------------------------------------------------------------------------------- 1 | @BookApi_HostAddress = http://localhost:5202 2 | 3 | GET {{BookApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /ch_17_refresh_token/BookApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookApi", "BookApi.csproj", "{565B12F3-B124-41A2-AC83-5028715780A1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {565B12F3-B124-41A2-AC83-5028715780A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {565B12F3-B124-41A2-AC83-5028715780A1}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Configuration/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Entities; 3 | using Entities.DTOs; 4 | 5 | namespace Configuration; 6 | 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap().ReverseMap(); 12 | CreateMap().ReverseMap(); 13 | CreateMap().ReverseMap(); 14 | CreateMap().ReverseMap(); 15 | CreateMap().ReverseMap(); 16 | } 17 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Collections.Generic; 4 | 5 | namespace Entities; 6 | 7 | public class Book 8 | { 9 | public int Id { get; set; } 10 | 11 | public String? Title { get; set; } 12 | public Decimal Price { get; set; } 13 | public String? URL { get; set; } 14 | 15 | public int CategoryId { get; set; } 16 | public Category? Category { get; set; } // navigation property 17 | public Book() 18 | { 19 | URL = "/images/default.jpg"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Entities; 4 | 5 | public class Category 6 | { 7 | public int CategoryId { get; set; } 8 | public String? CategoryName { get; set; } 9 | 10 | [JsonIgnore] 11 | public ICollection? Books { get; set; } // collection navigation property 12 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/BookDto.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.DTOs; 2 | 3 | public record BookDto : BookDtoBase 4 | { 5 | public int Id { get; init; } 6 | public Category Category { get; init; } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/BookDtoBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public abstract record BookDtoBase 6 | { 7 | [MinLength(2, ErrorMessage = "The title should include at least two characters.")] 8 | [MaxLength(25, ErrorMessage = "The title must be 25 characters or less.")] 9 | public String Title { get; init; } 10 | 11 | [Range(1, 100, ErrorMessage = "Price must be between 1 and 100.")] 12 | public Decimal Price { get; init; } 13 | 14 | [Required(ErrorMessage = "Category ID is required.")] 15 | public int CategoryId { get; init; } 16 | } 17 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/BookDtoForInsertion.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForInsertion : BookDtoBase 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/BookDtoForUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record BookDtoForUpdate : BookDtoBase 6 | { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/TokenDto.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.DTOs; 2 | 3 | public record TokenDto 4 | { 5 | public String AccessToken {get; init;} 6 | public String RefreshToken {get; init;} 7 | } 8 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/UserForAuthenticationDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record UserForAuthenticationDto 6 | { 7 | [Required(ErrorMessage = "Username is required!")] 8 | public String UserName { get; init; } 9 | 10 | [Required(ErrorMessage = "Password is required!")] 11 | public String Password { get; init; } 12 | } 13 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/DTOs/UserForRegistrationDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Entities.DTOs; 4 | 5 | public record UserForRegistrationDto 6 | { 7 | public String? FirstName { get; init; } 8 | public String? LastName { get; init; } 9 | 10 | [Required(ErrorMessage = "Username is required!")] 11 | public String UserName { get; init; } 12 | 13 | [Required(ErrorMessage = "Password is required!")] 14 | public String Password { get; init; } 15 | 16 | public String? Email { get; init; } 17 | public String? PhoneNumber { get; init; } 18 | public ICollection? Roles { get; init; } 19 | } 20 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/Exceptions/BookNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public sealed class BookNotFoundException : NotFoundException 3 | { 4 | public BookNotFoundException(int id) : base($"The book with {id} could not be found!") 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | namespace Entities.Exceptions; 3 | public class ErrorDetails 4 | { 5 | public int StatusCode { get; set; } 6 | public String? Message { get; set; } 7 | public String? AtOccured => DateTime.Now.ToLongDateString(); 8 | 9 | public override string ToString() 10 | { 11 | return JsonSerializer.Serialize(this); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/Exceptions/NotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace Entities.Exceptions; 2 | public abstract class NotFoundException : Exception 3 | { 4 | protected NotFoundException(string message) : base(message) 5 | { 6 | 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | 3 | namespace Entities; 4 | 5 | public class User : IdentityUser 6 | { 7 | public String? FirstName { get; set; } 8 | public String? LastName { get; set; } 9 | public string? RefreshToken { get; set; } 10 | public DateTime RefreshTokenExpiryTime { get; set; } 11 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/Models/get_api_books.wsd: -------------------------------------------------------------------------------- 1 | @startuml 2 | title Extended Sequence Diagram for [GET] /api/books Endpoint 3 | 4 | actor Client 5 | actor "Auth Service" as Auth 6 | participant "Book Service" as BookService 7 | participant "Book Repository" as BookRepo 8 | participant "Repository Base" as RepoBase 9 | participant API 10 | 11 | Client -> API: GET /api/books 12 | API -> Auth: Validate Token 13 | alt Valid Token and User/Role = Admin or User 14 | Auth --> API: Role Verified 15 | API -> BookService: Get Books 16 | BookService -> BookRepo: Fetch Books 17 | BookRepo -> RepoBase: Query Database 18 | RepoBase --> BookRepo: Data 19 | BookRepo --> BookService: List 20 | BookService --> API: List 21 | API --> Client: 200 OK with Book List 22 | else Unauthorized Role or Invalid Token 23 | Auth --> API: Invalid Token or Role 24 | API --> Client: 401 Unauthorized 25 | end 26 | 27 | @enduml 28 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:44417", 8 | "sslPort": 44371 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5202", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7141;http://localhost:5202", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Repositories/BookRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Repositories; 5 | 6 | public class BookRepository : RepositoryBase 7 | { 8 | public BookRepository(RepositoryContext context) : base(context) 9 | { 10 | 11 | } 12 | 13 | public override Book? Get(int id) => 14 | _context 15 | .Books 16 | .Include(b => b.Category) // eager loading 17 | .FirstOrDefault(b => b.Id.Equals(id)); 18 | 19 | public override List GetAll() => 20 | _context 21 | .Books 22 | .Include(b => b.Category) // eager loading 23 | .ToList(); 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Repositories/CategoryRepository.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | 3 | namespace Repositories; 4 | 5 | public class CategoryRepository : RepositoryBase 6 | { 7 | public CategoryRepository(RepositoryContext context) : base(context) 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/Repositories/RepositoryBase.cs: -------------------------------------------------------------------------------- 1 | namespace Repositories; 2 | 3 | public abstract class RepositoryBase 4 | where T:class, new() 5 | { 6 | protected readonly RepositoryContext _context; 7 | 8 | protected RepositoryBase(RepositoryContext context) 9 | { 10 | _context = context; 11 | } 12 | 13 | public virtual T? Get(int id) => 14 | _context 15 | .Set() 16 | .Find(id); 17 | 18 | public virtual List GetAll() => 19 | _context 20 | .Set() 21 | .ToList(); 22 | 23 | public virtual void Add(T item) 24 | { 25 | _context 26 | .Set() 27 | .Add(item); 28 | _context.SaveChanges(); 29 | } 30 | 31 | public virtual void Remove(T item) 32 | { 33 | _context 34 | .Set() 35 | .Remove(item); 36 | _context.SaveChanges(); 37 | } 38 | 39 | public virtual void Update(T item) 40 | { 41 | _context 42 | .Set() 43 | .Update(item); 44 | _context.SaveChanges(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Repositories/RepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using Entities; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Repositories; 7 | 8 | public class RepositoryContext : IdentityDbContext 9 | { 10 | public DbSet Books { get; set; } 11 | public DbSet Categories { get; set; } 12 | 13 | public RepositoryContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | base.OnModelCreating(modelBuilder); 22 | 23 | // Seed the Category entities first 24 | modelBuilder.Entity().HasData( 25 | new Category 26 | { 27 | CategoryId = 1, 28 | CategoryName = "Felsefe" 29 | }, 30 | new Category 31 | { 32 | CategoryId = 2, 33 | CategoryName = "Roman" 34 | }, 35 | new Category 36 | { 37 | CategoryId = 3, 38 | CategoryName = "Deneme" 39 | } 40 | ); 41 | 42 | // Seed the Book entities and reference the categories using CategoryId 43 | modelBuilder.Entity().HasData( 44 | new Book 45 | { 46 | Id = 1, 47 | Title = "Devlet", 48 | Price = 20.00M, 49 | URL = "/images/1.jpg", 50 | CategoryId = 1 51 | }, 52 | new Book 53 | { 54 | Id = 2, 55 | Title = "Ateşten Gömlek", 56 | Price = 15.50M, 57 | URL = "/images/1.jpg", 58 | CategoryId = 2 59 | }, 60 | new Book 61 | { 62 | Id = 3, 63 | Title = "Huzur", 64 | Price = 18.75M, 65 | URL = "/images/1.jpg", 66 | CategoryId = 3 67 | } 68 | ); 69 | 70 | // Seed the Role data 71 | modelBuilder.Entity().HasData( 72 | new IdentityRole 73 | { 74 | Name = "Admin", 75 | NormalizedName = "ADMIN" 76 | }, 77 | new IdentityRole 78 | { 79 | Name = "User", 80 | NormalizedName = "USER" 81 | } 82 | ); 83 | } 84 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/Services/AuthorService.cs: -------------------------------------------------------------------------------- 1 | // Author Servis gelecek -------------------------------------------------------------------------------- /ch_17_refresh_token/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | 5 | // namespace Services; 6 | 7 | // public class BookService : IBookService 8 | // { 9 | // private readonly List _bookList; 10 | // public BookService() 11 | // { 12 | // // seed data 13 | // _bookList = new List() 14 | // { 15 | // new Book { Id = 1, Title = "Devlet", Price = 20.00M }, 16 | // new Book { Id = 2, Title = "Ateşten Gömlek", Price = 15.50M }, 17 | // new Book { Id = 3, Title = "Huzur", Price = 18.75M } 18 | // }; 19 | // } 20 | 21 | // public List GetBooks() => _bookList; 22 | 23 | // public int Count => _bookList.Count; 24 | 25 | // public Book? GetBookById(int id) => 26 | // _bookList.FirstOrDefault(b => b.Id.Equals(id)); 27 | 28 | // public void AddBook(Book newBook) 29 | // { 30 | // newBook.Id = _bookList.Max(b => b.Id) + 1; 31 | // _bookList.Add(newBook); 32 | // } 33 | 34 | // public Book UpdateBook(int id, Book updateBook) 35 | // { 36 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 37 | // if (book is null) 38 | // { 39 | // throw new BookNotFoundException(id); 40 | // } 41 | 42 | // book.Title = updateBook.Title; 43 | // book.Price = updateBook.Price; 44 | 45 | // return book; 46 | // } 47 | 48 | // public void DeleteBook(int id) 49 | // { 50 | // var book = _bookList.FirstOrDefault(b => b.Id.Equals(id)); 51 | // if (book is not null) 52 | // { 53 | // _bookList.Remove(book); 54 | // } 55 | // else 56 | // { 57 | // throw new BookNotFoundException(id); 58 | // } 59 | // } 60 | // } -------------------------------------------------------------------------------- /ch_17_refresh_token/Services/BookServiceV2.cs: -------------------------------------------------------------------------------- 1 | // using Abstracts; 2 | // using Entities; 3 | // using Entities.Exceptions; 4 | // using Repositories; 5 | 6 | // namespace Services; 7 | 8 | // public class BookServiceV2 : IBookService 9 | // { 10 | // private readonly RepositoryContext _context; 11 | 12 | // public BookServiceV2(RepositoryContext context) 13 | // { 14 | // _context = context; 15 | // } 16 | 17 | // public int Count => _context.Books.ToList().Count; 18 | 19 | // public void AddBook(Book item) 20 | // { 21 | // _context.Books.Add(item); 22 | // _context.SaveChanges(); 23 | // } 24 | 25 | // public void DeleteBook(int id) 26 | // { 27 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 28 | // if (book is not null) 29 | // { 30 | // _context.Books.Remove(book); 31 | // _context.SaveChanges(); 32 | // } 33 | // else 34 | // { 35 | // throw new BookNotFoundException(id); 36 | // } 37 | // } 38 | 39 | // public Book? GetBookById(int id) => 40 | // _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 41 | 42 | // public List GetBooks() => 43 | // _context.Books.ToList(); 44 | 45 | 46 | // public Book UpdateBook(int id, Book item) 47 | // { 48 | // var book = _context.Books.FirstOrDefault(b => b.Id.Equals(id)); 49 | // if (book is null) 50 | // { 51 | // throw new BookNotFoundException(id); 52 | // } 53 | 54 | // book.Title = item.Title; 55 | // book.Price = item.Price; 56 | // _context.SaveChanges(); 57 | // return book; 58 | // } 59 | // } 60 | -------------------------------------------------------------------------------- /ch_17_refresh_token/Services/BookServiceV3.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Abstracts; 3 | using AutoMapper; 4 | using Configuration; 5 | using Entities; 6 | using Entities.DTOs; 7 | using Entities.Exceptions; 8 | using Repositories; 9 | 10 | namespace Services; 11 | 12 | public class BookServiceV3 : IBookService 13 | { 14 | private readonly BookRepository _bookRepo; 15 | private readonly IMapper _mapper; 16 | 17 | public BookServiceV3(BookRepository bookRepo, IMapper mapper) 18 | { 19 | _bookRepo = bookRepo; 20 | _mapper = mapper; 21 | } 22 | 23 | public int Count => _bookRepo.GetAll().Count; 24 | 25 | public Book AddBook(BookDtoForInsertion item) 26 | { 27 | Validate(item); 28 | var book = _mapper.Map(item); 29 | _bookRepo.Add(book); 30 | return book; 31 | } 32 | 33 | public void DeleteBook(int id) 34 | { 35 | id.VadaliteIdInRange(); 36 | 37 | var book = _bookRepo.Get(id); 38 | if (book is not null) 39 | _bookRepo.Remove(book); 40 | else 41 | throw new BookNotFoundException(id); 42 | } 43 | 44 | public BookDto? GetBookById(int id) 45 | { 46 | id.VadaliteIdInRange(); 47 | 48 | var book = _bookRepo.Get(id); 49 | 50 | if (book is null) 51 | { 52 | throw new BookNotFoundException(id); 53 | } 54 | return _mapper.Map(book); 55 | } 56 | 57 | 58 | public List GetBooks() 59 | { 60 | var books = _bookRepo.GetAll(); 61 | return _mapper.Map>(books); 62 | } 63 | 64 | public Book UpdateBook(int id, BookDtoForUpdate item) 65 | { 66 | id.VadaliteIdInRange(); 67 | Validate(item); 68 | var book = _bookRepo.Get(id); 69 | if (book is null) 70 | { 71 | throw new BookNotFoundException(id); 72 | } 73 | _mapper.Map(item, book); 74 | _bookRepo.Update(book); 75 | return book; 76 | } 77 | 78 | 79 | 80 | private void Validate(T item) 81 | { 82 | var validationResults = new List(); 83 | var context = new ValidationContext(item); 84 | var isValid = Validator.TryValidateObject(item, context, validationResults, true); 85 | 86 | if(!isValid) 87 | { 88 | var errors = string.Join(" ", validationResults.Select(v => v.ErrorMessage)); 89 | throw new ValidationException(errors); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ch_17_refresh_token/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ch_17_refresh_token/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "sqlite": "Data Source = database.db;" 11 | }, 12 | "JwtSettings":{ 13 | "validIssuer": "bookapi", 14 | "validAudience":"https://localhost:3000", 15 | "secretKey":"samsununiversitesiyazilimmuhendisligibolumusamsununiversitesiyazilimmuhendisligibolumu", 16 | "expire":60 17 | } 18 | } -------------------------------------------------------------------------------- /ch_17_refresh_token/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcomert/minimal-apis/5c61b9589b3ae1a9168cab1b8f14cc0ba7ffcb90/ch_17_refresh_token/database.db --------------------------------------------------------------------------------