├── Dockerfile ├── dotnet-app.http ├── Controllers ├── AuthController.cs ├── Global │ └── GlobalController.cs └── User │ └── UserController.cs ├── README.md ├── Program.cs ├── .dockerignore ├── appsettings.Development.json ├── Services └── User │ ├── Interface.cs │ └── UserService.cs ├── Shared ├── Config.cs ├── CustomError.cs └── Startup.cs ├── appsettings.json ├── .gitignore ├── Data └── AppDbContext.cs ├── docker-compose.yml ├── Models └── User.cs ├── dotnet-app.csproj ├── dotnet-app.sln └── Properties └── launchSettings.json /Dockerfile: -------------------------------------------------------------------------------- 1 | From As -------------------------------------------------------------------------------- /dotnet-app.http: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Controllers/AuthController.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotnet-api 2 | 3 | # run app host reload 4 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using dotnet_app.Shared; 2 | 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | Startup.Run(builder); 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .env 3 | .git 4 | .gitignore 5 | .vs 6 | .vscode 7 | docker-compose.yml 8 | docker-compose.*.yml 9 | */bin 10 | */obj 11 | 12 | Dockerfile -------------------------------------------------------------------------------- /appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Services/User/Interface.cs: -------------------------------------------------------------------------------- 1 | using User.Models; 2 | 3 | namespace dotnet_app.Services.User 4 | { 5 | public interface IUserService 6 | { 7 | UserEntity CreateUser(UserEntity user); 8 | } 9 | } -------------------------------------------------------------------------------- /Shared/Config.cs: -------------------------------------------------------------------------------- 1 | using dotnet_app.Services.User; 2 | namespace dotnet_app.Shared 3 | { 4 | public static class ServiceRegistration 5 | { 6 | public static void RegisterServices(IServiceCollection services) 7 | { 8 | services.AddScoped(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "PostgresDB": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Information", 8 | "Microsoft.AspNetCore": "Warning" 9 | } 10 | }, 11 | "AllowedHosts": "*" 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.*~ 3 | project.lock.json 4 | .DS_Store 5 | *.pyc 6 | 7 | .vscode 8 | 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | msbuild.log 25 | msbuild.err 26 | msbuild.wrn 27 | 28 | 29 | .vs/ -------------------------------------------------------------------------------- /Controllers/Global/GlobalController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace dotnet_app.Controllers.Global 4 | { 5 | [ApiController] 6 | [Route("/")] 7 | public class GlobalController : ControllerBase 8 | { 9 | [HttpGet] 10 | public ActionResult Get() 11 | { 12 | return "Api is running ..."; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Data/AppDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using User.Models; 3 | 4 | namespace dotnet_app.Data 5 | { 6 | public class ApplicationDbContext : DbContext 7 | { 8 | public ApplicationDbContext(DbContextOptions options) 9 | : base(options) 10 | { 11 | } 12 | 13 | public DbSet Users { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | postgres: 5 | image: postgres:latest 6 | environment: 7 | POSTGRES_USER: postgres 8 | POSTGRES_PASSWORD: postgres 9 | POSTGRES_DB: postgres 10 | PGDATA: /data/postgres 11 | # volumes: 12 | # - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql 13 | restart: unless-stopped 14 | ports: 15 | - "5432:5432" -------------------------------------------------------------------------------- /Services/User/UserService.cs: -------------------------------------------------------------------------------- 1 | using dotnet_app.Data; 2 | using User.Models; 3 | 4 | namespace dotnet_app.Services.User 5 | { 6 | public class UserService(ApplicationDbContext dbContext) : IUserService 7 | { 8 | private readonly ApplicationDbContext _dbContext = dbContext; 9 | 10 | public UserEntity CreateUser(UserEntity user) 11 | { 12 | _dbContext.Users.Add(user); 13 | _dbContext.SaveChanges(); 14 | return user; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Models/User.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace User.Models 5 | { 6 | public class UserEntity 7 | { 8 | public int Id { get; set; } 9 | 10 | [Required(ErrorMessage = "Name is required")] 11 | [StringLength(10, ErrorMessage = "Name is invalid length")] 12 | public required string Name { get; set; } 13 | 14 | [Required(ErrorMessage = "Email is required")] 15 | [StringLength(200)] 16 | [EmailAddress(ErrorMessage = "Invalid Email Address")] 17 | public required string Email { get; set; } 18 | 19 | [Required(ErrorMessage = "Password is required")] 20 | [StringLength(10)] 21 | public required string Password { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /dotnet-app.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | dotnet_app 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Shared/CustomError.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace dotnet_app.Shared 4 | { 5 | public class CustomError 6 | 7 | { 8 | public static BadRequestObjectResult CustomErrorResponse(ActionContext actionContext) 9 | { 10 | var errorRecordList = actionContext.ModelState 11 | .Where(modelError => modelError.Value.Errors.Count > 0) 12 | .Select(modelError => new 13 | { 14 | ErrorField = modelError.Key, 15 | ErrorDescription = modelError.Value.Errors.FirstOrDefault().ErrorMessage 16 | }).ToList(); 17 | 18 | string concatenatedMessage = string.Empty; 19 | foreach (var error in errorRecordList) 20 | { 21 | concatenatedMessage += error.ErrorField.Replace("_", " ") + ": " + error.ErrorDescription + ","; 22 | } 23 | concatenatedMessage = concatenatedMessage; 24 | return new BadRequestObjectResult(new 25 | { 26 | success = "failed", 27 | message = concatenatedMessage 28 | }); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /dotnet-app.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}") = "dotnet-app", "dotnet-app.csproj", "{8F5E458D-C9A3-4CEE-A2ED-09404518B7D1}" 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 | {8F5E458D-C9A3-4CEE-A2ED-09404518B7D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8F5E458D-C9A3-4CEE-A2ED-09404518B7D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8F5E458D-C9A3-4CEE-A2ED-09404518B7D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8F5E458D-C9A3-4CEE-A2ED-09404518B7D1}.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 = {E195C01C-98DB-493A-9218-4CC9EE747FAB} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /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:34567", 8 | "sslPort": 44379 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:4000", 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:7233;http://localhost:5020", 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 | -------------------------------------------------------------------------------- /Controllers/User/UserController.cs: -------------------------------------------------------------------------------- 1 | using dotnet_app.Services.User; 2 | using dotnet_app.Shared; 3 | using Microsoft.AspNetCore.Mvc; 4 | using User.Models; 5 | 6 | namespace dotnet_app.Controllers.User 7 | { 8 | [ApiController] 9 | [Route("api/user")] 10 | public class UserController(IUserService userService) : ControllerBase 11 | 12 | 13 | { 14 | private readonly IUserService _userService = userService; 15 | 16 | [HttpGet] 17 | public ActionResult> Get() 18 | { 19 | 20 | return new string[] { "user1", "user2", "user3" }; 21 | } 22 | 23 | 24 | [HttpGet("{id}")] 25 | public ActionResult Get(int id) 26 | { 27 | 28 | return "user" + id; 29 | } 30 | 31 | // POST: api/user 32 | [HttpPost] 33 | public IActionResult Post([FromBody] UserEntity value) 34 | { 35 | var error = CustomError.CustomErrorResponse(this.ControllerContext); 36 | if (error != null) 37 | { 38 | return error; 39 | } 40 | var user = _userService.CreateUser(value); 41 | return Ok(user); 42 | } 43 | 44 | 45 | [HttpPut("{id}")] 46 | public ActionResult Put(int id, [FromBody] string value) 47 | { 48 | 49 | return Ok(); 50 | } 51 | 52 | 53 | [HttpDelete("{id}")] 54 | public ActionResult Delete(int id) 55 | { 56 | 57 | return Ok(); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Shared/Startup.cs: -------------------------------------------------------------------------------- 1 | using dotnet_app.Data; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace dotnet_app.Shared 6 | { 7 | public static class Startup 8 | { 9 | 10 | private static void Setup(WebApplicationBuilder builder) 11 | { 12 | builder.Services.AddControllers(); 13 | builder.Services.AddEndpointsApiExplorer(); 14 | builder.Services.AddSwaggerGen(); 15 | 16 | // setupDB 17 | var connectionString = 18 | builder.Configuration.GetConnectionString("PostgresDB") ?? 19 | throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); 20 | builder.Services.AddEntityFrameworkNpgsql().AddDbContext(options => 21 | options.UseNpgsql(connectionString)); 22 | 23 | builder.Services.Configure(options => options. = actionContext => 24 | { 25 | return CustomErrorResponse(actionContext); 26 | }) 27 | 28 | //Register services 29 | ServiceRegistration.RegisterServices(builder.Services); 30 | } 31 | 32 | private static WebApplication Build(WebApplicationBuilder builder) 33 | { 34 | var app = builder.Build(); 35 | return app; 36 | 37 | } 38 | 39 | public static void Run(WebApplicationBuilder builder) 40 | { 41 | Setup(builder); 42 | var app = Build(builder); 43 | 44 | // checked connection to database 45 | using (var scope = app.Services.CreateScope()) 46 | { 47 | var dbContext = scope.ServiceProvider.GetRequiredService(); 48 | if (dbContext.Database.CanConnect().Equals(true)) 49 | { 50 | dbContext.Database.EnsureCreated(); 51 | Console.WriteLine("Successfully connected to PostgreSQL database."); 52 | } 53 | else 54 | { 55 | throw new InvalidOperationException("Failed to connect to PostgreSQL database."); 56 | } 57 | } 58 | 59 | // checked Environment 60 | if (app.Environment.IsDevelopment()) 61 | { 62 | app.UseSwagger(); 63 | app.UseSwaggerUI(); 64 | } 65 | 66 | 67 | app.UseCors("CorsPolicy"); 68 | 69 | app.UseRouting(); 70 | 71 | app.UseAuthorization(); 72 | 73 | app.MapControllers(); 74 | 75 | app.Run(url: "http://localhost:4000"); 76 | } 77 | 78 | } 79 | } 80 | --------------------------------------------------------------------------------