├── .devcontainer ├── debug │ ├── Dockerfile │ ├── compose.yml │ └── devcontainer.json └── dev │ ├── Dockerfile │ ├── devcontainer.json │ ├── docker-compose.yml │ └── mssql │ ├── installSQLtools.sh │ ├── postCreateCommand.sh │ └── setup.sql ├── .github └── dependabot.yml ├── .gitignore ├── Program.cs ├── Properties └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── workspaces.csproj └── workspaces.http /.devcontainer/debug/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm 2 | -------------------------------------------------------------------------------- /.devcontainer/debug/compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | build: 4 | context: . 5 | dockerfile: Dockerfile 6 | 7 | volumes: 8 | #- ../..:/workspaces:cached 9 | - ..:/workspaces:cached 10 | 11 | # Overrides default command so things don't shut down after the process ends. 12 | command: sleep infinity 13 | 14 | # Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 15 | # user: root 16 | 17 | # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 18 | # (Adding the "ports" property to this file will not forward from a Codespace.) 19 | fake-calls: 20 | image: alpine/curl:latest 21 | entrypoint: 22 | - /bin/sh 23 | - -c 24 | - | 25 | sleep 5 26 | while true; do 27 | curl "http://app:5010/weatherforecast" 28 | sleep 0.5 29 | done 30 | depends_on: 31 | - app 32 | -------------------------------------------------------------------------------- /.devcontainer/debug/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Debug Configuration", 3 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 4 | // "image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm", 5 | // "build": { 6 | // "dockerfile": "Dockerfile" 7 | // }, 8 | "dockerComposeFile": "compose.yml", 9 | "service": "app", 10 | // "workspaceFolder": "/workspaces", 11 | "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", 12 | "features": { 13 | "ghcr.io/nikiforovall/devcontainer-features/dotnet-aspire:1": {} 14 | }, 15 | "forwardPorts": [ 16 | 5010 17 | ], 18 | "portsAttributes": { 19 | "5010": { 20 | "protocol": "http" 21 | } 22 | }, 23 | "customizations": { 24 | "vscode": { 25 | "settings": { 26 | "workbench.colorTheme": "Abyss" 27 | }, 28 | "extensions": [ 29 | "ms-dotnettools.csdevkit", 30 | "GitHub.copilot", 31 | "GitHub.copilot-chat" 32 | ] 33 | } 34 | }, 35 | "postStartCommand": "dotnet watch run --urls http://+:5010" 36 | } -------------------------------------------------------------------------------- /.devcontainer/dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm 2 | 3 | # Install SQL Tools: SQLPackage and sqlcmd 4 | COPY mssql/installSQLtools.sh installSQLtools.sh 5 | RUN bash ./installSQLtools.sh \ 6 | && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts 7 | 8 | # [Optional] Uncomment this section to install additional OS packages. 9 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 10 | # && apt-get -y install --no-install-recommends 11 | 12 | # [Optional] Uncomment this line to install global node packages. 13 | RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install --lts && nvm use --lts && npm install -g typescript" 2>&1 14 | # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 15 | -------------------------------------------------------------------------------- /.devcontainer/dev/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/dotnet-mssql 3 | { 4 | "name": "Dev Configuration", 5 | "dockerComposeFile": "docker-compose.yml", 6 | "service": "app", 7 | "workspaceFolder": "/workspaces", 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | // "features": {}, 10 | // Configure tool-specific properties. 11 | "customizations": { 12 | // Configure properties specific to VS Code. 13 | "vscode": { 14 | // Set *default* container specific settings.json values on container create. 15 | "settings": { 16 | "workbench.colorTheme": "Visual Studio Dark", 17 | "mssql.connections": [ 18 | { 19 | "server": "localhost,1433", 20 | "database": "", 21 | "authenticationType": "SqlLogin", 22 | "user": "sa", 23 | "password": "P@ssw0rd", 24 | "emptyPasswordInput": false, 25 | "savePassword": false, 26 | "profileName": "mssql-container" 27 | } 28 | ] 29 | }, 30 | // Add the IDs of extensions you want installed when the container is created. 31 | "extensions": [ 32 | "ms-dotnettools.csharp", 33 | "ms-mssql.mssql", 34 | "ms-dotnettools.csdevkit" 35 | ] 36 | } 37 | }, 38 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 39 | // "forwardPorts": [5000, 5001], 40 | // "portsAttributes": { 41 | // "5001": { 42 | // "protocol": "https" 43 | // } 44 | // } 45 | // postCreateCommand.sh parameters: $1=SA password, $2=dacpac path, $3=sql script(s) path 46 | "postCreateCommand": "bash .devcontainer/dev/mssql/postCreateCommand.sh 'P@ssw0rd' './bin/Debug/' './.devcontainer/dev/mssql/' && dotnet dev-certs https --trust", 47 | "features": { 48 | "ghcr.io/devcontainers/features/common-utils:2": { 49 | "installZsh": true, 50 | "configureZshAsDefaultShell": true, 51 | "installOhMyZsh": true, 52 | "installOhMyZshConfig": true, 53 | "upgradePackages": true 54 | } 55 | } 56 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 57 | // "remoteUser": "root" 58 | } -------------------------------------------------------------------------------- /.devcontainer/dev/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | 9 | volumes: 10 | - ../..:/workspaces:cached 11 | 12 | # Overrides default command so things don't shut down after the process ends. 13 | command: sleep infinity 14 | 15 | # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. 16 | network_mode: service:db 17 | 18 | # Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 19 | # user: root 20 | 21 | # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 22 | # (Adding the "ports" property to this file will not forward from a Codespace.) 23 | 24 | db: 25 | image: mcr.microsoft.com/mssql/server:2019-latest 26 | restart: unless-stopped 27 | environment: 28 | SA_PASSWORD: P@ssw0rd 29 | ACCEPT_EULA: Y 30 | 31 | # Add "forwardPorts": ["db:1433"] to **devcontainer.json** to forward MSSQL locally. 32 | # (Adding the "ports" property to this file will not forward from a Codespace.) 33 | -------------------------------------------------------------------------------- /.devcontainer/dev/mssql/installSQLtools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Installing mssql-tools" 3 | curl -sSL https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT) 4 | DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]') 5 | CODENAME=$(lsb_release -cs) 6 | echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-${DISTRO}-${CODENAME}-prod ${CODENAME} main" > /etc/apt/sources.list.d/microsoft.list 7 | apt-get update 8 | ACCEPT_EULA=Y apt-get -y install unixodbc-dev msodbcsql17 libunwind8 mssql-tools 9 | 10 | echo "Installing sqlpackage" 11 | curl -sSL -o sqlpackage.zip "https://aka.ms/sqlpackage-linux" 12 | mkdir /opt/sqlpackage 13 | unzip sqlpackage.zip -d /opt/sqlpackage 14 | rm sqlpackage.zip 15 | chmod a+x /opt/sqlpackage/sqlpackage 16 | -------------------------------------------------------------------------------- /.devcontainer/dev/mssql/postCreateCommand.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dacpac="false" 3 | sqlfiles="false" 4 | SApassword=$1 5 | dacpath=$2 6 | sqlpath=$3 7 | 8 | echo "SELECT * FROM SYS.DATABASES" | dd of=testsqlconnection.sql 9 | for i in {1..60}; 10 | do 11 | /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SApassword -d master -i testsqlconnection.sql > /dev/null 12 | if [ $? -eq 0 ] 13 | then 14 | echo "SQL server ready" 15 | break 16 | else 17 | echo "Not ready yet..." 18 | sleep 1 19 | fi 20 | done 21 | rm testsqlconnection.sql 22 | 23 | for f in $dacpath/* 24 | do 25 | if [ $f == $dacpath/*".dacpac" ] 26 | then 27 | dacpac="true" 28 | echo "Found dacpac $f" 29 | fi 30 | done 31 | 32 | for f in $sqlpath/* 33 | do 34 | if [ $f == $sqlpath/*".sql" ] 35 | then 36 | sqlfiles="true" 37 | echo "Found SQL file $f" 38 | fi 39 | done 40 | 41 | if [ $sqlfiles == "true" ] 42 | then 43 | for f in $sqlpath/* 44 | do 45 | if [ $f == $sqlpath/*".sql" ] 46 | then 47 | echo "Executing $f" 48 | /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SApassword -d master -i $f 49 | fi 50 | done 51 | fi 52 | 53 | if [ $dacpac == "true" ] 54 | then 55 | for f in $dacpath/* 56 | do 57 | if [ $f == $dacpath/*".dacpac" ] 58 | then 59 | dbname=$(basename $f ".dacpac") 60 | echo "Deploying dacpac $f" 61 | /opt/sqlpackage/sqlpackage /Action:Publish /SourceFile:$f /TargetServerName:localhost /TargetDatabaseName:$dbname /TargetUser:sa /TargetPassword:$SApassword 62 | fi 63 | done 64 | fi 65 | -------------------------------------------------------------------------------- /.devcontainer/dev/mssql/setup.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE ApplicationDB; 2 | GO 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | - package-ecosystem: "nuget" 14 | directory: "/" 15 | schedule: 16 | interval: weekly 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.*~ 3 | project.lock.json 4 | .DS_Store 5 | *.pyc 6 | nupkg/ 7 | 8 | # Visual Studio Code 9 | .vscode/ 10 | 11 | # Rider 12 | .idea/ 13 | 14 | # Visual Studio 15 | .vs/ 16 | 17 | # Fleet 18 | .fleet/ 19 | 20 | # Code Rush 21 | .cr/ 22 | 23 | # User-specific files 24 | *.suo 25 | *.user 26 | *.userosscache 27 | *.sln.docstates 28 | 29 | # Build results 30 | bin/[Dd]ebug/ 31 | [Dd]ebugPublic/ 32 | [Rr]elease/ 33 | [Rr]eleases/ 34 | x64/ 35 | x86/ 36 | build/ 37 | bld/ 38 | [Bb]in/ 39 | [Oo]bj/ 40 | [Oo]ut/ 41 | msbuild.log 42 | msbuild.err 43 | msbuild.wrn -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | // Add services to the container. 4 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 5 | builder.Services.AddEndpointsApiExplorer(); 6 | builder.Services.AddSwaggerGen(); 7 | 8 | // Configure logging 9 | builder.Logging.ClearProviders(); 10 | builder.Logging.AddConsole(); 11 | 12 | var app = builder.Build(); 13 | 14 | // Configure the HTTP request pipeline. 15 | if (app.Environment.IsDevelopment()) 16 | { 17 | app.UseSwagger(); 18 | app.UseSwaggerUI(); 19 | } 20 | 21 | app.UseHttpsRedirection(); 22 | 23 | var summaries = new[] 24 | { 25 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 26 | }; 27 | 28 | app.MapGet("/weatherforecast", () => 29 | { 30 | 31 | app.Logger.LogInformation("GetWeatherForecast called"); 32 | 33 | var forecast = Enumerable.Range(1, 5).Select(index => 34 | new WeatherForecast 35 | ( 36 | DateOnly.FromDateTime(DateTime.Now.AddDays(index)), 37 | Random.Shared.Next(-20, 55), 38 | summaries[Random.Shared.Next(summaries.Length)] 39 | )) 40 | .ToArray(); 41 | return forecast; 42 | }) 43 | .WithName("GetWeatherForecast") 44 | .WithOpenApi(); 45 | 46 | app.Run(); 47 | 48 | record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 49 | { 50 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 51 | } 52 | -------------------------------------------------------------------------------- /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:22562", 8 | "sslPort": 44396 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:7204;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 | -------------------------------------------------------------------------------- /appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /workspaces.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /workspaces.http: -------------------------------------------------------------------------------- 1 | @workspaces_HostAddress = http://localhost:5295 2 | 3 | GET {{workspaces_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | --------------------------------------------------------------------------------