├── .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
--------------------------------------------------------------------------------