├── .gitignore ├── README.md ├── amazon-api-gateway ├── Gateway.Demo.sln ├── HelloWorld │ ├── Function.cs │ ├── HelloWorld.csproj │ ├── Properties │ │ └── launchSettings.json │ ├── Readme.md │ └── aws-lambda-tools-defaults.json └── StudentManager │ ├── Function.cs │ ├── Properties │ └── launchSettings.json │ ├── Readme.md │ ├── Student.cs │ ├── StudentManager.csproj │ └── aws-lambda-tools-defaults.json ├── amazon-sns-in-30-minutes ├── LambdaSub │ ├── Function.cs │ ├── LambdaSub.csproj │ ├── Properties │ │ └── launchSettings.json │ ├── Readme.md │ └── aws-lambda-tools-defaults.json ├── OrderService │ ├── Models │ │ ├── CreateOrderRequest.cs │ │ ├── OrderCreatedNotification.cs │ │ └── ProductDetail.cs │ ├── OrderService.csproj │ ├── OrderService.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json └── Shoply.sln ├── amazon-sqs-in-dotnet ├── AmazonSQS.Demo.sln ├── Consumer.Api │ ├── Consumer.Api.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── UserRegisteredEventConsumer.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Messages │ ├── IEvent.cs │ ├── Messages.csproj │ └── UserRegisteredEvent.cs └── Producer.Api │ ├── Models │ └── UserRegistrationCommand.cs │ ├── Producer.Api.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── aws-lambda-dotnet-6 ├── FirstLambda │ ├── FirstLambda.csproj │ ├── Function.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Readme.md │ └── aws-lambda-tools-defaults.json └── LambdaDemo.sln ├── deploy-blazor-wasm-to-aws-s3 ├── BlazorClient.sln └── BlazorClient │ ├── App.razor │ ├── BlazorClient.csproj │ ├── Layout │ ├── MainLayout.razor │ ├── MainLayout.razor.css │ ├── NavMenu.razor │ └── NavMenu.razor.css │ ├── Models │ └── User.cs │ ├── Pages │ ├── Counter.razor │ ├── Home.razor │ ├── Users.razor │ └── Weather.razor │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── IUserService.cs │ └── UserService.cs │ ├── _Imports.razor │ └── wwwroot │ ├── css │ └── app.css │ ├── favicon.png │ ├── icon-192.png │ ├── icon-512.png │ ├── index.html │ ├── lib │ └── bootstrap │ │ └── dist │ │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-grid.rtl.css │ │ ├── bootstrap-grid.rtl.css.map │ │ ├── bootstrap-grid.rtl.min.css │ │ ├── bootstrap-grid.rtl.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap-reboot.rtl.css │ │ ├── bootstrap-reboot.rtl.css.map │ │ ├── bootstrap-reboot.rtl.min.css │ │ ├── bootstrap-reboot.rtl.min.css.map │ │ ├── bootstrap-utilities.css │ │ ├── bootstrap-utilities.css.map │ │ ├── bootstrap-utilities.min.css │ │ ├── bootstrap-utilities.min.css.map │ │ ├── bootstrap-utilities.rtl.css │ │ ├── bootstrap-utilities.rtl.css.map │ │ ├── bootstrap-utilities.rtl.min.css │ │ ├── bootstrap-utilities.rtl.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.css.map │ │ ├── bootstrap.rtl.css │ │ ├── bootstrap.rtl.css.map │ │ ├── bootstrap.rtl.min.css │ │ └── bootstrap.rtl.min.css.map │ │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.esm.js │ │ ├── bootstrap.esm.js.map │ │ ├── bootstrap.esm.min.js │ │ ├── bootstrap.esm.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── manifest.webmanifest │ ├── sample-data │ └── weather.json │ ├── service-worker.js │ └── service-worker.published.js ├── deploying-aspnet-core-web-api-with-aws-ecs-fargate ├── .dockerignore ├── BookManager.Api.sln └── BookManager.Api │ ├── BookManager.Api.csproj │ ├── BookManager.Api.http │ ├── DTOs │ └── CreateBookRequest.cs │ ├── Dockerfile │ ├── Domain │ └── Book.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── BookService.cs │ └── IBookService.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── deploying-aspnet-core-web-api-with-aws-lambda ├── .gitignore ├── Products.Api │ ├── Data │ │ └── Product.cs │ ├── Dtos │ │ ├── CreateProductRequest.cs │ │ └── UpdateProductRequest.cs │ ├── Products.Api.csproj │ ├── Products.Api.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── IProductService.cs │ │ └── ProductService.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── aws-lambda-tools-defaults.json ├── SimpleApi │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── SimpleApi.csproj │ ├── SimpleApi.http │ ├── appsettings.Development.json │ ├── appsettings.json │ └── aws-lambda-tools-defaults.json └── WebApiOnLambda.sln ├── dotnet-on-aws-series.png ├── dynamodb-dotnet-7-webapi ├── DynamoDB.Demo.sln └── DynamoDB.Demo │ ├── Controllers │ └── ProductsController.cs │ ├── DynamoDB.Demo.csproj │ ├── Product.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── hosting-aspnet-core-webapi-on-amazon-ec2 ├── .dockerignore ├── BookManager.Api.sln ├── BookManager.Api │ ├── AppDbContext.cs │ ├── BookManager.Api.csproj │ ├── BookManager.Api.http │ ├── BookManager.Api.sln │ ├── DTOs │ │ └── CreateBookRequest.cs │ ├── Domain │ │ └── Book.cs │ ├── Migrations │ │ ├── 20241014011119_Initial.Designer.cs │ │ ├── 20241014011119_Initial.cs │ │ └── AppDbContextModelSnapshot.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── BookService.cs │ │ └── IBookService.cs │ ├── appsettings.Development.json │ ├── appsettings.Docker.json │ ├── appsettings.json │ └── docker-compose.yml └── user-script.md ├── lambda-authorizer ├── HelloWorld │ ├── Function.cs │ ├── HelloWorld.csproj │ ├── Properties │ │ └── launchSettings.json │ ├── Readme.md │ └── aws-lambda-tools-defaults.json ├── LambdaAuth │ ├── Function.cs │ ├── LambdaAuth.csproj │ ├── Properties │ │ └── launchSettings.json │ ├── Readme.md │ └── aws-lambda-tools-defaults.json ├── LambdaAuthorizer.Demo.sln └── TokenGeneration │ ├── Function.cs │ ├── Properties │ └── launchSettings.json │ ├── Readme.md │ ├── TokenGeneration.csproj │ └── aws-lambda-tools-defaults.json ├── s3-dotnet-7-webapi ├── S3.Demo.API │ ├── Controllers │ │ ├── BucketsController.cs │ │ ├── FilesController.cs │ │ └── WeatherForecastController.cs │ ├── Models │ │ └── S3ObjectDto.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── S3.Demo.API.csproj │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json └── S3.Demo.sln └── send-emails-from-dotnet-using-amazon-ses └── SESDemo ├── SESDemo.sln └── SESDemo ├── Models ├── MailOptions.cs └── MailRequest.cs ├── Program.cs ├── Properties └── launchSettings.json ├── SESDemo.csproj ├── SESDemo.http ├── Services ├── IEmailService.cs ├── SdkEmailService.cs └── SmtpEmailService.cs ├── appsettings.Development.json └── appsettings.json /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # Tye 66 | .tye/ 67 | 68 | # ASP.NET Scaffolding 69 | ScaffoldingReadMe.txt 70 | 71 | # StyleCop 72 | StyleCopReport.xml 73 | 74 | # Files built by Visual Studio 75 | *_i.c 76 | *_p.c 77 | *_h.h 78 | *.ilk 79 | *.meta 80 | *.obj 81 | *.iobj 82 | *.pch 83 | *.pdb 84 | *.ipdb 85 | *.pgc 86 | *.pgd 87 | *.rsp 88 | *.sbr 89 | *.tlb 90 | *.tli 91 | *.tlh 92 | *.tmp 93 | *.tmp_proj 94 | *_wpftmp.csproj 95 | *.log 96 | *.tlog 97 | *.vspscc 98 | *.vssscc 99 | .builds 100 | *.pidb 101 | *.svclog 102 | *.scc 103 | 104 | # Chutzpah Test files 105 | _Chutzpah* 106 | 107 | # Visual C++ cache files 108 | ipch/ 109 | *.aps 110 | *.ncb 111 | *.opendb 112 | *.opensdf 113 | *.sdf 114 | *.cachefile 115 | *.VC.db 116 | *.VC.VC.opendb 117 | 118 | # Visual Studio profiler 119 | *.psess 120 | *.vsp 121 | *.vspx 122 | *.sap 123 | 124 | # Visual Studio Trace Files 125 | *.e2e 126 | 127 | # TFS 2012 Local Workspace 128 | $tf/ 129 | 130 | # Guidance Automation Toolkit 131 | *.gpState 132 | 133 | # ReSharper is a .NET coding add-in 134 | _ReSharper*/ 135 | *.[Rr]e[Ss]harper 136 | *.DotSettings.user 137 | 138 | # TeamCity is a build add-in 139 | _TeamCity* 140 | 141 | # DotCover is a Code Coverage Tool 142 | *.dotCover 143 | 144 | # AxoCover is a Code Coverage Tool 145 | .axoCover/* 146 | !.axoCover/settings.json 147 | 148 | # Coverlet is a free, cross platform Code Coverage Tool 149 | coverage*.json 150 | coverage*.xml 151 | coverage*.info 152 | 153 | # Visual Studio code coverage results 154 | *.coverage 155 | *.coveragexml 156 | 157 | # NCrunch 158 | _NCrunch_* 159 | .*crunch*.local.xml 160 | nCrunchTemp_* 161 | 162 | # MightyMoose 163 | *.mm.* 164 | AutoTest.Net/ 165 | 166 | # Web workbench (sass) 167 | .sass-cache/ 168 | 169 | # Installshield output folder 170 | [Ee]xpress/ 171 | 172 | # DocProject is a documentation generator add-in 173 | DocProject/buildhelp/ 174 | DocProject/Help/*.HxT 175 | DocProject/Help/*.HxC 176 | DocProject/Help/*.hhc 177 | DocProject/Help/*.hhk 178 | DocProject/Help/*.hhp 179 | DocProject/Help/Html2 180 | DocProject/Help/html 181 | 182 | # Click-Once directory 183 | publish/ 184 | 185 | # Publish Web Output 186 | *.[Pp]ublish.xml 187 | *.azurePubxml 188 | # Note: Comment the next line if you want to checkin your web deploy settings, 189 | # but database connection strings (with potential passwords) will be unencrypted 190 | *.pubxml 191 | *.publishproj 192 | 193 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 194 | # checkin your Azure Web App publish settings, but sensitive information contained 195 | # in these scripts will be unencrypted 196 | PublishScripts/ 197 | 198 | # NuGet Packages 199 | *.nupkg 200 | # NuGet Symbol Packages 201 | *.snupkg 202 | # The packages folder can be ignored because of Package Restore 203 | **/[Pp]ackages/* 204 | # except build/, which is used as an MSBuild target. 205 | !**/[Pp]ackages/build/ 206 | # Uncomment if necessary however generally it will be regenerated when needed 207 | #!**/[Pp]ackages/repositories.config 208 | # NuGet v3's project.json files produces more ignorable files 209 | *.nuget.props 210 | *.nuget.targets 211 | 212 | # Microsoft Azure Build Output 213 | csx/ 214 | *.build.csdef 215 | 216 | # Microsoft Azure Emulator 217 | ecf/ 218 | rcf/ 219 | 220 | # Windows Store app package directories and files 221 | AppPackages/ 222 | BundleArtifacts/ 223 | Package.StoreAssociation.xml 224 | _pkginfo.txt 225 | *.appx 226 | *.appxbundle 227 | *.appxupload 228 | 229 | # Visual Studio cache files 230 | # files ending in .cache can be ignored 231 | *.[Cc]ache 232 | # but keep track of directories ending in .cache 233 | !?*.[Cc]ache/ 234 | 235 | # Others 236 | ClientBin/ 237 | ~$* 238 | *~ 239 | *.dbmdl 240 | *.dbproj.schemaview 241 | *.jfm 242 | *.pfx 243 | *.publishsettings 244 | orleans.codegen.cs 245 | 246 | # Including strong name files can present a security risk 247 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 248 | #*.snk 249 | 250 | # Since there are multiple workflows, uncomment next line to ignore bower_components 251 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 252 | #bower_components/ 253 | 254 | # RIA/Silverlight projects 255 | Generated_Code/ 256 | 257 | # Backup & report files from converting an old project file 258 | # to a newer Visual Studio version. Backup files are not needed, 259 | # because we have git ;-) 260 | _UpgradeReport_Files/ 261 | Backup*/ 262 | UpgradeLog*.XML 263 | UpgradeLog*.htm 264 | ServiceFabricBackup/ 265 | *.rptproj.bak 266 | 267 | # SQL Server files 268 | *.mdf 269 | *.ldf 270 | *.ndf 271 | 272 | # Business Intelligence projects 273 | *.rdl.data 274 | *.bim.layout 275 | *.bim_*.settings 276 | *.rptproj.rsuser 277 | *- [Bb]ackup.rdl 278 | *- [Bb]ackup ([0-9]).rdl 279 | *- [Bb]ackup ([0-9][0-9]).rdl 280 | 281 | # Microsoft Fakes 282 | FakesAssemblies/ 283 | 284 | # GhostDoc plugin setting file 285 | *.GhostDoc.xml 286 | 287 | # Node.js Tools for Visual Studio 288 | .ntvs_analysis.dat 289 | node_modules/ 290 | 291 | # Visual Studio 6 build log 292 | *.plg 293 | 294 | # Visual Studio 6 workspace options file 295 | *.opt 296 | 297 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 298 | *.vbw 299 | 300 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 301 | *.vbp 302 | 303 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 304 | *.dsw 305 | *.dsp 306 | 307 | # Visual Studio 6 technical files 308 | *.ncb 309 | *.aps 310 | 311 | # Visual Studio LightSwitch build output 312 | **/*.HTMLClient/GeneratedArtifacts 313 | **/*.DesktopClient/GeneratedArtifacts 314 | **/*.DesktopClient/ModelManifest.xml 315 | **/*.Server/GeneratedArtifacts 316 | **/*.Server/ModelManifest.xml 317 | _Pvt_Extensions 318 | 319 | # Paket dependency manager 320 | .paket/paket.exe 321 | paket-files/ 322 | 323 | # FAKE - F# Make 324 | .fake/ 325 | 326 | # CodeRush personal settings 327 | .cr/personal 328 | 329 | # Python Tools for Visual Studio (PTVS) 330 | __pycache__/ 331 | *.pyc 332 | 333 | # Cake - Uncomment if you are using it 334 | # tools/** 335 | # !tools/packages.config 336 | 337 | # Tabs Studio 338 | *.tss 339 | 340 | # Telerik's JustMock configuration file 341 | *.jmconfig 342 | 343 | # BizTalk build output 344 | *.btp.cs 345 | *.btm.cs 346 | *.odx.cs 347 | *.xsd.cs 348 | 349 | # OpenCover UI analysis results 350 | OpenCover/ 351 | 352 | # Azure Stream Analytics local run output 353 | ASALocalRun/ 354 | 355 | # MSBuild Binary and Structured Log 356 | *.binlog 357 | 358 | # NVidia Nsight GPU debugger configuration file 359 | *.nvuser 360 | 361 | # MFractors (Xamarin productivity tool) working folder 362 | .mfractor/ 363 | 364 | # Local History for Visual Studio 365 | .localhistory/ 366 | 367 | # Visual Studio History (VSHistory) files 368 | .vshistory/ 369 | 370 | # BeatPulse healthcheck temp database 371 | healthchecksdb 372 | 373 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 374 | MigrationBackup/ 375 | 376 | # Ionide (cross platform F# VS Code tools) working folder 377 | .ionide/ 378 | 379 | # Fody - auto-generated XML schema 380 | FodyWeavers.xsd 381 | 382 | # VS Code files for those working on multiple tools 383 | .vscode/* 384 | !.vscode/settings.json 385 | !.vscode/tasks.json 386 | !.vscode/launch.json 387 | !.vscode/extensions.json 388 | *.code-workspace 389 | 390 | # Local History for Visual Studio Code 391 | .history/ 392 | 393 | # Windows Installer files from build outputs 394 | *.cab 395 | *.msi 396 | *.msix 397 | *.msm 398 | *.msp 399 | 400 | # JetBrains Rider 401 | *.sln.iml 402 | 403 | ## 404 | ## Visual studio for Mac 405 | ## 406 | 407 | 408 | # globs 409 | Makefile.in 410 | *.userprefs 411 | *.usertasks 412 | config.make 413 | config.status 414 | aclocal.m4 415 | install-sh 416 | autom4te.cache/ 417 | *.tar.gz 418 | tarballs/ 419 | test-results/ 420 | 421 | # Mac bundle stuff 422 | *.dmg 423 | *.app 424 | 425 | # content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore 426 | # General 427 | .DS_Store 428 | .AppleDouble 429 | .LSOverride 430 | 431 | # Icon must end with two \r 432 | Icon 433 | 434 | 435 | # Thumbnails 436 | ._* 437 | 438 | # Files that might appear in the root of a volume 439 | .DocumentRevisions-V100 440 | .fseventsd 441 | .Spotlight-V100 442 | .TemporaryItems 443 | .Trashes 444 | .VolumeIcon.icns 445 | .com.apple.timemachine.donotpresent 446 | 447 | # Directories potentially created on remote AFP share 448 | .AppleDB 449 | .AppleDesktop 450 | Network Trash Folder 451 | Temporary Items 452 | .apdisk 453 | 454 | # content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore 455 | # Windows thumbnail cache files 456 | Thumbs.db 457 | ehthumbs.db 458 | ehthumbs_vista.db 459 | 460 | # Dump file 461 | *.stackdump 462 | 463 | # Folder config file 464 | [Dd]esktop.ini 465 | 466 | # Recycle Bin used on file shares 467 | $RECYCLE.BIN/ 468 | 469 | # Windows Installer files 470 | *.cab 471 | *.msi 472 | *.msix 473 | *.msm 474 | *.msp 475 | 476 | # Windows shortcuts 477 | *.lnk 478 | 479 | # Vim temporary swap files 480 | *.swp 481 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # .NET on AWS Series 2 | 3 | #### By Mukesh Murugan | [LinkedIn](https://www.linkedin.com/in/iammukeshm/) | [Blog](https://www.codewithmukesh.com) | [Youtube](https://www.youtube.com/@codewithmukesh?sub_confirmation=1) 4 | 5 | Watch the Entire Playlist here - [.NET on AWS Playlist](https://www.youtube.com/playlist?list=PLigUNuP4l_bPnDeuk0DlO_Fba4bcIVSNN) 6 | 7 | [![Watch the .NET on AWS Playlist](/dotnet-on-aws-series.png)](https://www.youtube.com/playlist?list=PLigUNuP4l_bPnDeuk0DlO_Fba4bcIVSNN) 8 | 9 | ## Configuring AWS Credentials for .NET Applications 10 | 11 | - Blog Post - https://codewithmukesh.com/blog/aws-credentials-for-dotnet-applications/ 12 | - Youtube Video - https://www.youtube.com/watch?v=oY0-1mj4oCo 13 | 14 | ## Working with AWS S3 in ASP.NET Core Web API | .NET 7 15 | 16 | - Blog post - https://codewithmukesh.com/blog/working-with-aws-s3-using-aspnet-core/ 17 | - Youtube Video - https://www.youtube.com/watch?v=2q5jA813ZiI 18 | 19 | ## Getting Started with AWS Lambda | Serverless Application 20 | 21 | - Blog post - https://codewithmukesh.com/blog/aws-lambda-with-net-6/ 22 | - Youtube Video - https://www.youtube.com/watch?v=WaZn_8_2RTQ 23 | 24 | ## Getting Started with DynamoDB | Serverless | CRUD in ASP.NET Core 25 | 26 | - Blog post - https://codewithmukesh.com/blog/crud-with-dynamodb-in-aspnet-core/ 27 | - Youtube Video - https://www.youtube.com/watch?v=BJYDWMN8taI 28 | 29 | ## Amazon API Gateway for .NET Developers | .NET CRUD Application with AWS Lambda & DynamoDB 30 | 31 | - Blog post - https://codewithmukesh.com/blog/amazon-api-gateway-with-dotnet/ 32 | - Youtube Video - https://youtu.be/OGpQnNyAYyY 33 | 34 | ## How to Secure Amazon API Gateway with Lambda Authorizer? 35 | 36 | - Blog post - https://codewithmukesh.com/blog/aws-lambda-authorizer-in-dotnet/ 37 | - Youtube Video - https://youtu.be/OGpQnNyAYyY 38 | 39 | ## Serverless ASP.NET Core Web API with AWS Lambda | How to Deploy your ASP.NET Core Web API to AWS Lambda? 40 | 41 | - Blog post - https://codewithmukesh.com/blog/hosting-aspnet-core-web-api-with-aws-lambda/ 42 | - Youtube Video - https://youtu.be/VKGzlXLmFmg 43 | 44 | ## Deploy .NET 8 Web API in under 10 Minutes with AWS Elastic Beanstalk! 45 | 46 | - Blog post - https://codewithmukesh.com/blog/deploying-aspnet-core-web-api-to-aws-elastic-beanstalk-using-aws-codepipeline/ 47 | - Youtube Video - https://www.youtube.com/watch?v=-ZO0_SBUT2E 48 | 49 | ## Deploying .NET Web API to Amazon ECS Fargate Easily! 50 | 51 | - Blog post - https://codewithmukesh.com/blog/deploy-aspnet-core-web-api-to-amazon-ecs/ 52 | - Youtube Video - https://www.youtube.com/watch?v=_6wAICffp9U 53 | -------------------------------------------------------------------------------- /amazon-api-gateway/Gateway.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34004.107 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "HelloWorld\HelloWorld.csproj", "{0F01DAAC-659D-462C-B96B-F8ADB2181259}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StudentManager", "StudentManager\StudentManager.csproj", "{E183E0AC-8420-4FC1-8D03-92DCECA5C0B8}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {0F01DAAC-659D-462C-B96B-F8ADB2181259}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {0F01DAAC-659D-462C-B96B-F8ADB2181259}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {0F01DAAC-659D-462C-B96B-F8ADB2181259}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {0F01DAAC-659D-462C-B96B-F8ADB2181259}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {E183E0AC-8420-4FC1-8D03-92DCECA5C0B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E183E0AC-8420-4FC1-8D03-92DCECA5C0B8}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E183E0AC-8420-4FC1-8D03-92DCECA5C0B8}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {E183E0AC-8420-4FC1-8D03-92DCECA5C0B8}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {A2C8C66C-9292-4907-8830-376D359AC1EC} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /amazon-api-gateway/HelloWorld/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.APIGatewayEvents; 2 | using Amazon.Lambda.Core; 3 | using System.Text.Json; 4 | 5 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 6 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 7 | 8 | namespace HelloWorld; 9 | 10 | public class Function 11 | { 12 | 13 | /// 14 | /// A simple function that takes a string and does a ToUpper 15 | /// 16 | /// 17 | /// 18 | /// 19 | public string FunctionHandler(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context) 20 | { 21 | Console.WriteLine(JsonSerializer.Serialize(request)); 22 | string name = string.Empty; 23 | if (request != null && request.PathParameters != null) 24 | { 25 | request.PathParameters.TryGetValue("name", out name); 26 | 27 | } 28 | if (string.IsNullOrEmpty(name)) name = "John Doe"; 29 | var message = $"Hello {name}, from AWS Lambda"; 30 | return message; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /amazon-api-gateway/HelloWorld/HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /amazon-api-gateway/HelloWorld/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /amazon-api-gateway/HelloWorld/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "HelloWorld/test/HelloWorld.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "HelloWorld/src/HelloWorld" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /amazon-api-gateway/HelloWorld/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "HelloWorld::HelloWorld.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "hello-world", 19 | "package-type" : "Zip", 20 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_hello-world-0", 21 | "function-subnets" : "", 22 | "function-security-groups" : "", 23 | "tracing-mode" : "PassThrough", 24 | "environment-variables" : "", 25 | "image-tag" : "", 26 | "function-description" : "" 27 | } -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2; 2 | using Amazon.DynamoDBv2.DataModel; 3 | using Amazon.Lambda.APIGatewayEvents; 4 | using Amazon.Lambda.Core; 5 | using System.Text.Json; 6 | 7 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 8 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 9 | 10 | namespace StudentManager; 11 | 12 | public class Function 13 | { 14 | 15 | /// 16 | /// A simple function that takes a string and does a ToUpper 17 | /// 18 | /// 19 | /// 20 | /// 21 | public async Task FunctionHandler(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context) 22 | { 23 | Console.WriteLine(JsonSerializer.Serialize(request)); 24 | AmazonDynamoDBClient client = new AmazonDynamoDBClient(); 25 | DynamoDBContext dbContext = new DynamoDBContext(client); 26 | if (request.RouteKey.Contains("GET /")) 27 | { 28 | var data = await dbContext.ScanAsync(default).GetRemainingAsync(); 29 | return new APIGatewayHttpApiV2ProxyResponse 30 | { 31 | Body = JsonSerializer.Serialize(data), 32 | StatusCode = 200 33 | }; 34 | } 35 | else if (request.RouteKey.Contains("POST /") && request.Body != null) 36 | { 37 | var newStudent = JsonSerializer.Deserialize(request.Body); 38 | await dbContext.SaveAsync(newStudent); 39 | return new APIGatewayHttpApiV2ProxyResponse 40 | { 41 | Body = $"Student with Id {newStudent?.Id} Created", 42 | StatusCode = 201 43 | }; 44 | } 45 | else 46 | { 47 | return new APIGatewayHttpApiV2ProxyResponse 48 | { 49 | Body = "Bad Request", 50 | StatusCode = 400 51 | }; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "StudentManager/test/StudentManager.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "StudentManager/src/StudentManager" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/Student.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | 3 | namespace StudentManager 4 | { 5 | [DynamoDBTable("students")] 6 | public class Student 7 | { 8 | [DynamoDBHashKey("id")] 9 | public string Id { get; set; } 10 | 11 | [DynamoDBProperty("first_name")] 12 | public string? FirstName { get; set; } 13 | 14 | [DynamoDBProperty("last_name")] 15 | public string? LastName { get; set; } 16 | 17 | [DynamoDBProperty("class")] 18 | public int Class { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/StudentManager.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /amazon-api-gateway/StudentManager/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "StudentManager::StudentManager.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "student-manager", 19 | "function-description" : "", 20 | "package-type" : "Zip", 21 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_student-manager-0", 22 | "function-subnets" : "", 23 | "function-security-groups" : "", 24 | "tracing-mode" : "PassThrough", 25 | "environment-variables" : "", 26 | "image-tag" : "" 27 | } -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/LambdaSub/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.Core; 2 | using Amazon.Lambda.SNSEvents; 3 | 4 | 5 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 6 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 7 | 8 | namespace LambdaSub; 9 | 10 | public class Function 11 | { 12 | /// 13 | /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment 14 | /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the 15 | /// region the Lambda function is executed in. 16 | /// 17 | public Function() 18 | { 19 | 20 | } 21 | 22 | 23 | /// 24 | /// This method is called for every Lambda invocation. This method takes in an SNS event object and can be used 25 | /// to respond to SNS messages. 26 | /// 27 | /// The event for the Lambda function handler to process. 28 | /// The ILambdaContext that provides methods for logging and describing the Lambda environment. 29 | /// 30 | public async Task FunctionHandler(SNSEvent evnt, ILambdaContext context) 31 | { 32 | foreach (var record in evnt.Records) 33 | { 34 | await ProcessRecordAsync(record, context); 35 | } 36 | } 37 | 38 | private async Task ProcessRecordAsync(SNSEvent.SNSRecord record, ILambdaContext context) 39 | { 40 | context.Logger.LogInformation($"Processed SNS with subject: {record.Sns.Subject} and message: {record.Sns.Message}"); 41 | 42 | // TODO: Do interesting work based on the new message 43 | await Task.CompletedTask; 44 | } 45 | } -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/LambdaSub/LambdaSub.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/LambdaSub/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net8.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-8.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/LambdaSub/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Simple SNS Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler responds to events on an Amazon SNS service. 10 | 11 | After deploying your function you must configure an Amazon SNS service as an event source to trigger your Lambda function. 12 | 13 | ## Here are some steps to follow from Visual Studio: 14 | 15 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 16 | 17 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 18 | 19 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 20 | 21 | To configure event sources for your deployed function use the Event Sources tab in the opened Function View window. 22 | 23 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 24 | 25 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 26 | 27 | ## Here are some steps to follow to get started from the command line: 28 | 29 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 30 | 31 | Install Amazon.Lambda.Tools Global Tools if not already installed. 32 | ``` 33 | dotnet tool install -g Amazon.Lambda.Tools 34 | ``` 35 | 36 | If already installed check if new version is available. 37 | ``` 38 | dotnet tool update -g Amazon.Lambda.Tools 39 | ``` 40 | 41 | Execute unit tests 42 | ``` 43 | cd "LambdaSub/test/LambdaSub.Tests" 44 | dotnet test 45 | ``` 46 | 47 | Deploy function to AWS Lambda 48 | ``` 49 | cd "LambdaSub/src/LambdaSub" 50 | dotnet lambda deploy-function 51 | ``` 52 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/LambdaSub/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "us-east-1", 11 | "configuration" : "Release", 12 | "function-runtime" : "dotnet8", 13 | "function-memory-size" : 512, 14 | "function-timeout" : 30, 15 | "function-handler" : "LambdaSub::LambdaSub.Function::FunctionHandler", 16 | "framework" : "net8.0", 17 | "function-name" : "demosub", 18 | "package-type" : "Zip", 19 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_demosub", 20 | "function-architecture" : "x86_64", 21 | "function-subnets" : "", 22 | "function-security-groups" : "", 23 | "tracing-mode" : "PassThrough", 24 | "environment-variables" : "", 25 | "image-tag" : "" 26 | } -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/Models/CreateOrderRequest.cs: -------------------------------------------------------------------------------- 1 | namespace OrderService.Models; 2 | 3 | public record CreateOrderRequest(int OrderId, int CustomerId, List ProductDetails); 4 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/Models/OrderCreatedNotification.cs: -------------------------------------------------------------------------------- 1 | namespace OrderService.Models; 2 | 3 | public class OrderCreatedNotification 4 | { 5 | public int OrderId { get; init; } 6 | public int CustomerId { get; init; } 7 | public DateTime CreatedAt { get; init; } 8 | public List ProductDetails { get; init; } 9 | 10 | public OrderCreatedNotification(int orderId, int customerId, List productDetails) 11 | { 12 | OrderId = orderId; 13 | CustomerId = customerId; 14 | CreatedAt = DateTime.UtcNow; 15 | ProductDetails = productDetails; 16 | } 17 | } -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/Models/ProductDetail.cs: -------------------------------------------------------------------------------- 1 | namespace OrderService.Models; 2 | 3 | public record ProductDetail(int ProductId, string Name, int Quantity); -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/OrderService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/OrderService.http: -------------------------------------------------------------------------------- 1 | @OrderService_HostAddress = http://localhost:5121 2 | 3 | GET {{OrderService_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SimpleNotificationService; 2 | using Amazon.SimpleNotificationService.Model; 3 | using OrderService.Models; 4 | using System.Text.Json; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | builder.Services.AddEndpointsApiExplorer(); 8 | builder.Services.AddSwaggerGen(); 9 | 10 | builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions()); 11 | builder.Services.AddAWSService(); 12 | 13 | 14 | var app = builder.Build(); 15 | if (app.Environment.IsDevelopment()) 16 | { 17 | app.UseSwagger(); 18 | app.UseSwaggerUI(); 19 | } 20 | 21 | app.UseHttpsRedirection(); 22 | 23 | app.MapPost("/", async (CreateOrderRequest request, IAmazonSimpleNotificationService sns) => 24 | { 25 | // assume the incoming request is processed and saved to the database. 26 | 27 | // create notification 28 | var notification = new OrderCreatedNotification(request.OrderId, request.CustomerId, request.ProductDetails); 29 | 30 | // create topic if needed 31 | var topicName = "OrderCreated"; 32 | var topicArn = string.Empty; 33 | var topicExists = await sns.FindTopicAsync(topicName); 34 | if (topicExists != null) 35 | { 36 | topicArn = topicExists.TopicArn; 37 | } 38 | else 39 | { 40 | var newTopic = await sns.CreateTopicAsync(topicName); 41 | topicArn = newTopic.TopicArn; 42 | } 43 | 44 | // create publish request 45 | var publishRequest = new PublishRequest() 46 | { 47 | TopicArn = topicArn, 48 | Message = JsonSerializer.Serialize(notification), 49 | Subject = $"Order#{request.OrderId}" 50 | }; 51 | 52 | publishRequest.MessageAttributes.Add("Scope", new MessageAttributeValue() 53 | { 54 | DataType = "String", 55 | StringValue = "Lambda" 56 | }); 57 | 58 | await sns.PublishAsync(publishRequest); 59 | }); 60 | 61 | app.Run(); -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/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:10284", 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:5121", 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:7145;http://localhost:5121", 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 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/OrderService/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /amazon-sns-in-30-minutes/Shoply.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35707.178 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderService", "OrderService\OrderService.csproj", "{5451EEC8-B268-4BD2-ACD8-877AB6BC4739}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LambdaSub", "LambdaSub\LambdaSub.csproj", "{DE918CAA-E03E-4BA4-876A-C3D4EE375341}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5451EEC8-B268-4BD2-ACD8-877AB6BC4739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5451EEC8-B268-4BD2-ACD8-877AB6BC4739}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5451EEC8-B268-4BD2-ACD8-877AB6BC4739}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {5451EEC8-B268-4BD2-ACD8-877AB6BC4739}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {DE918CAA-E03E-4BA4-876A-C3D4EE375341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {DE918CAA-E03E-4BA4-876A-C3D4EE375341}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {DE918CAA-E03E-4BA4-876A-C3D4EE375341}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {DE918CAA-E03E-4BA4-876A-C3D4EE375341}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/AmazonSQS.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35514.174 d17.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Producer.Api", "Producer.Api\Producer.Api.csproj", "{637B0197-DE92-4645-8C00-32A59A6677AD}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Consumer.Api", "Consumer.Api\Consumer.Api.csproj", "{103C499C-0CDA-4D86-95BE-B6A0AA6C3347}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "Messages\Messages.csproj", "{5840ADC3-F821-4BBF-861B-A743D3679D1C}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {637B0197-DE92-4645-8C00-32A59A6677AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {637B0197-DE92-4645-8C00-32A59A6677AD}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {637B0197-DE92-4645-8C00-32A59A6677AD}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {637B0197-DE92-4645-8C00-32A59A6677AD}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {103C499C-0CDA-4D86-95BE-B6A0AA6C3347}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {103C499C-0CDA-4D86-95BE-B6A0AA6C3347}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {103C499C-0CDA-4D86-95BE-B6A0AA6C3347}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {103C499C-0CDA-4D86-95BE-B6A0AA6C3347}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {5840ADC3-F821-4BBF-861B-A743D3679D1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {5840ADC3-F821-4BBF-861B-A743D3679D1C}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {5840ADC3-F821-4BBF-861B-A743D3679D1C}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {5840ADC3-F821-4BBF-861B-A743D3679D1C}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/Consumer.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SQS; 2 | using Consumer.Api; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | // Add services to the container. 7 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 8 | builder.Services.AddOpenApi(); 9 | 10 | builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions()); 11 | builder.Services.AddAWSService(); 12 | builder.Services.AddHostedService(); 13 | 14 | var app = builder.Build(); 15 | 16 | // Configure the HTTP request pipeline. 17 | if (app.Environment.IsDevelopment()) 18 | { 19 | app.MapOpenApi(); 20 | } 21 | 22 | app.UseHttpsRedirection(); 23 | app.Run(); -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "applicationUrl": "http://localhost:5014", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": false, 17 | "applicationUrl": "https://localhost:7029;http://localhost:5014", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/UserRegisteredEventConsumer.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SQS; 2 | using Amazon.SQS.Model; 3 | 4 | namespace Consumer.Api; 5 | 6 | public class UserRegisteredEventConsumer(IAmazonSQS sqs, ILogger logger) : BackgroundService 7 | { 8 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 9 | { 10 | 11 | // assume that the name of the registered queue is 'user-registered' 12 | var queueName = "user-registered"; 13 | 14 | logger.LogInformation("Polling Queue {queueName}", queueName); 15 | 16 | // get queue url 17 | // or create a new queue if it doesnt already exist 18 | var queueUrl = string.Empty; 19 | try 20 | { 21 | var response = await sqs.GetQueueUrlAsync(queueName); 22 | queueUrl = response.QueueUrl; 23 | } 24 | catch (QueueDoesNotExistException) 25 | { 26 | logger.LogInformation("Queue {queueName} doesn't exist. Creating...", queueName); 27 | var response = await sqs.CreateQueueAsync(queueName); 28 | queueUrl = response.QueueUrl; 29 | } 30 | 31 | var receiveRequest = new ReceiveMessageRequest() 32 | { 33 | QueueUrl = queueUrl 34 | }; 35 | 36 | while (!stoppingToken.IsCancellationRequested) 37 | { 38 | var response = await sqs.ReceiveMessageAsync(receiveRequest); 39 | if (response.Messages.Count > 0) 40 | { 41 | foreach (var message in response.Messages) 42 | { 43 | logger.LogInformation("Received Message from Queue {queueName} with body as : \n {body}", queueName, message.Body); 44 | //perform some processing. 45 | //mock 2 seconds delay for processing 46 | Task.Delay(2000).Wait(); 47 | await sqs.DeleteMessageAsync(queueUrl, message.ReceiptHandle); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Consumer.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Messages/IEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Messages; 2 | public interface IEvent 3 | { 4 | } 5 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Messages/Messages.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Messages/UserRegisteredEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Messages; 2 | public class UserRegisteredEvent : IEvent 3 | { 4 | public Guid UserId { get; } 5 | public string UserName { get; } 6 | public string Email { get; } 7 | public DateTime CreatedDate { get; } 8 | 9 | public UserRegisteredEvent(Guid userId, string userName, string email) 10 | { 11 | UserId = userId; 12 | UserName = userName ?? throw new ArgumentNullException(nameof(userName)); 13 | Email = email ?? throw new ArgumentNullException(nameof(email)); 14 | CreatedDate = DateTime.UtcNow; 15 | } 16 | } -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/Models/UserRegistrationCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Producer.Api.Models; 2 | 3 | public record UserRegistrationCommand(string UserName, string Email); -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/Producer.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SQS; 2 | using Amazon.SQS.Model; 3 | using Messages; 4 | using Producer.Api.Models; 5 | using System.Text.Json; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 11 | builder.Services.AddOpenApi(); 12 | 13 | builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions()); 14 | builder.Services.AddAWSService(); 15 | 16 | var app = builder.Build(); 17 | 18 | // Configure the HTTP request pipeline. 19 | if (app.Environment.IsDevelopment()) 20 | { 21 | app.MapOpenApi(); 22 | } 23 | 24 | app.MapPost("/register", async (IAmazonSQS sqs, ILogger logger, UserRegistrationCommand command) => 25 | { 26 | // validate the incoming request object 27 | // register the user into the database 28 | var userId = Guid.NewGuid(); 29 | 30 | // create event to notify external services 31 | var userRegisteredEvent = new UserRegisteredEvent(userId, command.UserName, command.Email); 32 | 33 | // assume that the name of the registered queue is 'user-registered' 34 | var queueName = "user-registered"; 35 | 36 | // get queue url 37 | // or create a new queue if it doesnt already exist 38 | var queueUrl = string.Empty; 39 | try 40 | { 41 | var response = await sqs.GetQueueUrlAsync(queueName); 42 | queueUrl = response.QueueUrl; 43 | } 44 | catch (QueueDoesNotExistException) 45 | { 46 | logger.LogInformation("Queue {queueName} doesn't exist. Creating...", queueName); 47 | var response = await sqs.CreateQueueAsync(queueName); 48 | queueUrl = response.QueueUrl; 49 | } 50 | 51 | // create sqs request 52 | var sendMessageRequest = new SendMessageRequest() 53 | { 54 | QueueUrl = queueUrl, 55 | MessageBody = JsonSerializer.Serialize(userRegisteredEvent) 56 | }; 57 | logger.LogInformation("Publishing message to Queue {queueName} with body : \n {request}", queueName, sendMessageRequest.MessageBody); 58 | 59 | // send sqs request 60 | var result = await sqs.SendMessageAsync(sendMessageRequest); 61 | return Results.Ok(); 62 | }); 63 | 64 | app.UseHttpsRedirection(); 65 | app.Run(); -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "applicationUrl": "http://localhost:5026", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": false, 17 | "applicationUrl": "https://localhost:7130;http://localhost:5026", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /amazon-sqs-in-dotnet/Producer.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/FirstLambda/FirstLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/FirstLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.Core; 2 | 3 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 4 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 5 | 6 | namespace FirstLambda; 7 | 8 | public class Function 9 | { 10 | 11 | /// 12 | /// A simple function that takes a string and does a ToUpper 13 | /// 14 | /// 15 | /// 16 | /// 17 | public CreateProductResponse FunctionHandler(CreateProductRequest input, ILambdaContext context) 18 | { 19 | // Assume Product is Saved to DB 20 | var response = new CreateProductResponse(); 21 | response.ProductId = Guid.NewGuid().ToString(); 22 | response.Name = input.Name; 23 | response.Description = input.Description; 24 | return response; 25 | } 26 | public class CreateProductRequest 27 | { 28 | public string? Name { get; set; } 29 | public string? Description { get; set; } 30 | } 31 | public class CreateProductResponse 32 | { 33 | public string? ProductId { get; set; } 34 | public string? Name { get; set; } 35 | public string? Description { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/FirstLambda/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/FirstLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "FirstLambda/test/FirstLambda.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "FirstLambda/src/FirstLambda" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/FirstLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "FirstLambda::FirstLambda.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "firstLambda", 19 | "function-description" : "firstLambda", 20 | "package-type" : "Zip", 21 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_firstLambda", 22 | "function-subnets" : "", 23 | "function-security-groups" : "", 24 | "tracing-mode" : "PassThrough", 25 | "environment-variables" : "", 26 | "image-tag" : "" 27 | } -------------------------------------------------------------------------------- /aws-lambda-dotnet-6/LambdaDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.6.33801.468 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FirstLambda", "FirstLambda\FirstLambda.csproj", "{092E7444-2E75-4550-8E16-2441B6E0855E}" 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 | {092E7444-2E75-4550-8E16-2441B6E0855E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {092E7444-2E75-4550-8E16-2441B6E0855E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {092E7444-2E75-4550-8E16-2441B6E0855E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {092E7444-2E75-4550-8E16-2441B6E0855E}.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 = {D7303677-20D2-4E42-BEBC-5BB33E0368FE} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35728.132 d17.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorClient", "BlazorClient\BlazorClient.csproj", "{89BC2504-2862-4DA3-BA5C-14AF4CD36F38}" 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 | {89BC2504-2862-4DA3-BA5C-14AF4CD36F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {89BC2504-2862-4DA3-BA5C-14AF4CD36F38}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {89BC2504-2862-4DA3-BA5C-14AF4CD36F38}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {89BC2504-2862-4DA3-BA5C-14AF4CD36F38}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/BlazorClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | service-worker-assets.js 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 |
3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Layout/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row ::deep .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | text-decoration: none; 28 | } 29 | 30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { 31 | text-decoration: underline; 32 | } 33 | 34 | .top-row ::deep a:first-child { 35 | overflow: hidden; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | @media (max-width: 640.98px) { 40 | .top-row { 41 | justify-content: space-between; 42 | } 43 | 44 | .top-row ::deep a, .top-row ::deep .btn-link { 45 | margin-left: 0; 46 | } 47 | } 48 | 49 | @media (min-width: 641px) { 50 | .page { 51 | flex-direction: row; 52 | } 53 | 54 | .sidebar { 55 | width: 250px; 56 | height: 100vh; 57 | position: sticky; 58 | top: 0; 59 | } 60 | 61 | .top-row { 62 | position: sticky; 63 | top: 0; 64 | z-index: 1; 65 | } 66 | 67 | .top-row.auth ::deep a:first-child { 68 | flex: 1; 69 | text-align: right; 70 | width: 0; 71 | } 72 | 73 | .top-row, article { 74 | padding-left: 2rem !important; 75 | padding-right: 1.5rem !important; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Layout/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  9 | 10 | 34 | 35 | @code { 36 | private bool collapseNavMenu = true; 37 | 38 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; 39 | 40 | private void ToggleNavMenu() 41 | { 42 | collapseNavMenu = !collapseNavMenu; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Layout/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | min-height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .bi { 15 | display: inline-block; 16 | position: relative; 17 | width: 1.25rem; 18 | height: 1.25rem; 19 | margin-right: 0.75rem; 20 | top: -1px; 21 | background-size: cover; 22 | } 23 | 24 | .bi-house-door-fill-nav-menu { 25 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E"); 26 | } 27 | 28 | .bi-plus-square-fill-nav-menu { 29 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E"); 30 | } 31 | 32 | .bi-list-nested-nav-menu { 33 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E"); 34 | } 35 | 36 | .nav-item { 37 | font-size: 0.9rem; 38 | padding-bottom: 0.5rem; 39 | } 40 | 41 | .nav-item:first-of-type { 42 | padding-top: 1rem; 43 | } 44 | 45 | .nav-item:last-of-type { 46 | padding-bottom: 1rem; 47 | } 48 | 49 | .nav-item ::deep a { 50 | color: #d7d7d7; 51 | border-radius: 4px; 52 | height: 3rem; 53 | display: flex; 54 | align-items: center; 55 | line-height: 3rem; 56 | } 57 | 58 | .nav-item ::deep a.active { 59 | background-color: rgba(255,255,255,0.37); 60 | color: white; 61 | } 62 | 63 | .nav-item ::deep a:hover { 64 | background-color: rgba(255,255,255,0.1); 65 | color: white; 66 | } 67 | 68 | @media (min-width: 641px) { 69 | .navbar-toggler { 70 | display: none; 71 | } 72 | 73 | .collapse { 74 | /* Never collapse the sidebar for wide screens */ 75 | display: block; 76 | } 77 | 78 | .nav-scrollable { 79 | /* Allow sidebar to scroll for tall menus */ 80 | height: calc(100vh - 3.5rem); 81 | overflow-y: auto; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Models/User.cs: -------------------------------------------------------------------------------- 1 | namespace BlazorClient.Models; 2 | 3 | public class User 4 | { 5 | public int Id { get; set; } 6 | public string? Name { get; set; } 7 | public string? Username { get; set; } 8 | public string? Email { get; set; } 9 | public string? Phone { get; set; } 10 | public string? Website { get; set; } 11 | } -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Pages/Users.razor: -------------------------------------------------------------------------------- 1 | @page "/users" 2 | @using BlazorClient.Models 3 | @using BlazorClient.Services 4 | @inject IUserService UserService 5 | 6 | Users 7 | 8 |

Users

9 | 10 |

This component demonstrates fetching data from an external API.

11 | 12 | @if (users == null) 13 | { 14 |

Loading...

15 | } 16 | else 17 | { 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | @foreach (var user in users) 29 | { 30 | 31 | 32 | 33 | 34 | 35 | 36 | } 37 | 38 |
IdNameUsernameEmail
@user.Id@user.Name@user.Username@user.Email
39 | } 40 | 41 | @code { 42 | private IEnumerable? users; 43 | 44 | protected override async Task OnInitializedAsync() 45 | { 46 | users = await UserService.GetAllAsync(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Pages/Weather.razor: -------------------------------------------------------------------------------- 1 | @page "/weather" 2 | @inject HttpClient Http 3 | 4 | Weather 5 | 6 |

Weather

7 | 8 |

This component demonstrates fetching data from the server.

9 | 10 | @if (forecasts == null) 11 | { 12 |

Loading...

13 | } 14 | else 15 | { 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | @foreach (var forecast in forecasts) 27 | { 28 | 29 | 30 | 31 | 32 | 33 | 34 | } 35 | 36 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
37 | } 38 | 39 | @code { 40 | private WeatherForecast[]? forecasts; 41 | 42 | protected override async Task OnInitializedAsync() 43 | { 44 | forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); 45 | } 46 | 47 | public class WeatherForecast 48 | { 49 | public DateOnly Date { get; set; } 50 | 51 | public int TemperatureC { get; set; } 52 | 53 | public string? Summary { get; set; } 54 | 55 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Program.cs: -------------------------------------------------------------------------------- 1 | using BlazorClient; 2 | using BlazorClient.Services; 3 | using Microsoft.AspNetCore.Components.Web; 4 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 5 | 6 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 7 | builder.RootComponents.Add("#app"); 8 | builder.RootComponents.Add("head::after"); 9 | 10 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 11 | 12 | builder.Services.AddHttpClient(client => 13 | { 14 | client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com/"); 15 | }); 16 | 17 | 18 | await builder.Build().RunAsync(); 19 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 9 | "applicationUrl": "http://localhost:5131", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 19 | "applicationUrl": "https://localhost:7146;http://localhost:5131", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Services/IUserService.cs: -------------------------------------------------------------------------------- 1 | using BlazorClient.Models; 2 | 3 | namespace BlazorClient.Services; 4 | 5 | public interface IUserService 6 | { 7 | Task?> GetAllAsync(); 8 | } 9 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/Services/UserService.cs: -------------------------------------------------------------------------------- 1 | using BlazorClient.Models; 2 | using System.Net.Http.Json; 3 | 4 | namespace BlazorClient.Services; 5 | 6 | public class UserService : IUserService 7 | { 8 | private readonly HttpClient _httpClient; 9 | 10 | public UserService(HttpClient httpClient) 11 | { 12 | _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); 13 | } 14 | 15 | public async Task?> GetAllAsync() 16 | { 17 | var users = await _httpClient.GetFromJsonAsync>("users"); 18 | return users; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using BlazorClient 10 | @using BlazorClient.Layout 11 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 3 | } 4 | 5 | h1:focus { 6 | outline: none; 7 | } 8 | 9 | a, .btn-link { 10 | color: #0071c1; 11 | } 12 | 13 | .btn-primary { 14 | color: #fff; 15 | background-color: #1b6ec2; 16 | border-color: #1861ac; 17 | } 18 | 19 | .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { 20 | box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; 21 | } 22 | 23 | .content { 24 | padding-top: 1.1rem; 25 | } 26 | 27 | .valid.modified:not([type=checkbox]) { 28 | outline: 1px solid #26b050; 29 | } 30 | 31 | .invalid { 32 | outline: 1px solid red; 33 | } 34 | 35 | .validation-message { 36 | color: red; 37 | } 38 | 39 | #blazor-error-ui { 40 | color-scheme: light only; 41 | background: lightyellow; 42 | bottom: 0; 43 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 44 | box-sizing: border-box; 45 | display: none; 46 | left: 0; 47 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 48 | position: fixed; 49 | width: 100%; 50 | z-index: 1000; 51 | } 52 | 53 | #blazor-error-ui .dismiss { 54 | cursor: pointer; 55 | position: absolute; 56 | right: 0.75rem; 57 | top: 0.5rem; 58 | } 59 | 60 | .blazor-error-boundary { 61 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 62 | padding: 1rem 1rem 1rem 3.7rem; 63 | color: white; 64 | } 65 | 66 | .blazor-error-boundary::after { 67 | content: "An error has occurred." 68 | } 69 | 70 | .loading-progress { 71 | position: relative; 72 | display: block; 73 | width: 8rem; 74 | height: 8rem; 75 | margin: 20vh auto 1rem auto; 76 | } 77 | 78 | .loading-progress circle { 79 | fill: none; 80 | stroke: #e0e0e0; 81 | stroke-width: 0.6rem; 82 | transform-origin: 50% 50%; 83 | transform: rotate(-90deg); 84 | } 85 | 86 | .loading-progress circle:last-child { 87 | stroke: #1b6ec2; 88 | stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; 89 | transition: stroke-dasharray 0.05s ease-in-out; 90 | } 91 | 92 | .loading-progress-text { 93 | position: absolute; 94 | text-align: center; 95 | font-weight: bold; 96 | inset: calc(20vh + 3.25rem) 0 auto 0.2rem; 97 | } 98 | 99 | .loading-progress-text:after { 100 | content: var(--blazor-load-percentage-text, "Loading"); 101 | } 102 | 103 | code { 104 | color: #c02d76; 105 | } 106 | 107 | .form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { 108 | color: var(--bs-secondary-color); 109 | text-align: end; 110 | } 111 | 112 | .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { 113 | text-align: start; 114 | } -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewithmukesh/dotnet-on-aws-series/72e54de7bf3dd8701d7ce0a1440c4f9661349cfe/deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/favicon.png -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewithmukesh/dotnet-on-aws-series/72e54de7bf3dd8701d7ce0a1440c4f9661349cfe/deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/icon-192.png -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewithmukesh/dotnet-on-aws-series/72e54de7bf3dd8701d7ce0a1440c4f9661349cfe/deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/icon-512.png -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | BlazorClient 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 |
25 |
26 | 27 |
28 | An unhandled error has occurred. 29 | Reload 30 | 🗙 31 |
32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2024 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2024 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */ -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BlazorClient", 3 | "short_name": "BlazorClient", 4 | "id": "./", 5 | "start_url": "./", 6 | "display": "standalone", 7 | "background_color": "#ffffff", 8 | "theme_color": "#03173d", 9 | "prefer_related_applications": false, 10 | "icons": [ 11 | { 12 | "src": "icon-512.png", 13 | "type": "image/png", 14 | "sizes": "512x512" 15 | }, 16 | { 17 | "src": "icon-192.png", 18 | "type": "image/png", 19 | "sizes": "192x192" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2022-01-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing" 6 | }, 7 | { 8 | "date": "2022-01-07", 9 | "temperatureC": 14, 10 | "summary": "Bracing" 11 | }, 12 | { 13 | "date": "2022-01-08", 14 | "temperatureC": -13, 15 | "summary": "Freezing" 16 | }, 17 | { 18 | "date": "2022-01-09", 19 | "temperatureC": -16, 20 | "summary": "Balmy" 21 | }, 22 | { 23 | "date": "2022-01-10", 24 | "temperatureC": -2, 25 | "summary": "Chilly" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/service-worker.js: -------------------------------------------------------------------------------- 1 | // In development, always fetch from the network and do not enable offline support. 2 | // This is because caching would make development more difficult (changes would not 3 | // be reflected on the first load after each change). 4 | self.addEventListener('fetch', () => { }); 5 | -------------------------------------------------------------------------------- /deploy-blazor-wasm-to-aws-s3/BlazorClient/wwwroot/service-worker.published.js: -------------------------------------------------------------------------------- 1 | // Caution! Be sure you understand the caveats before publishing an application with 2 | // offline support. See https://aka.ms/blazor-offline-considerations 3 | 4 | self.importScripts('./service-worker-assets.js'); 5 | self.addEventListener('install', event => event.waitUntil(onInstall(event))); 6 | self.addEventListener('activate', event => event.waitUntil(onActivate(event))); 7 | self.addEventListener('fetch', event => event.respondWith(onFetch(event))); 8 | 9 | const cacheNamePrefix = 'offline-cache-'; 10 | const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; 11 | const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; 12 | const offlineAssetsExclude = [ /^service-worker\.js$/ ]; 13 | 14 | // Replace with your base path if you are hosting on a subfolder. Ensure there is a trailing '/'. 15 | const base = "/"; 16 | const baseUrl = new URL(base, self.origin); 17 | const manifestUrlList = self.assetsManifest.assets.map(asset => new URL(asset.url, baseUrl).href); 18 | 19 | async function onInstall(event) { 20 | console.info('Service worker: Install'); 21 | 22 | // Fetch and cache all matching items from the assets manifest 23 | const assetsRequests = self.assetsManifest.assets 24 | .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) 25 | .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) 26 | .map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' })); 27 | await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); 28 | } 29 | 30 | async function onActivate(event) { 31 | console.info('Service worker: Activate'); 32 | 33 | // Delete unused caches 34 | const cacheKeys = await caches.keys(); 35 | await Promise.all(cacheKeys 36 | .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) 37 | .map(key => caches.delete(key))); 38 | } 39 | 40 | async function onFetch(event) { 41 | let cachedResponse = null; 42 | if (event.request.method === 'GET') { 43 | // For all navigation requests, try to serve index.html from cache, 44 | // unless that request is for an offline resource. 45 | // If you need some URLs to be server-rendered, edit the following check to exclude those URLs 46 | const shouldServeIndexHtml = event.request.mode === 'navigate' 47 | && !manifestUrlList.some(url => url === event.request.url); 48 | 49 | const request = shouldServeIndexHtml ? 'index.html' : event.request; 50 | const cache = await caches.open(cacheName); 51 | cachedResponse = await cache.match(request); 52 | } 53 | 54 | return cachedResponse || fetch(event.request); 55 | } 56 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md 26 | !**/.gitignore 27 | !.git/HEAD 28 | !.git/config 29 | !.git/packed-refs 30 | !.git/refs/heads/** -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35027.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookManager.Api", "BookManager.Api\BookManager.Api.csproj", "{59F0A5C3-D417-4C5F-8C76-114795B72E41}" 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 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.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 = {F75518C1-E8FB-4F3B-9440-DEE6237D8E12} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/BookManager.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 85eea339-78af-4d58-86ab-7724678cff78 8 | Linux 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/BookManager.Api.http: -------------------------------------------------------------------------------- 1 | @BookManager.Api_HostAddress = http://localhost:5175 2 | 3 | GET {{BookManager.Api_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/DTOs/CreateBookRequest.cs: -------------------------------------------------------------------------------- 1 | namespace BookManager.Api.DTOs; 2 | 3 | public record CreateBookRequest(string Title, int PublishedYear, int Pages, string Summary); -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base 4 | USER app 5 | WORKDIR /app 6 | EXPOSE 8080 7 | EXPOSE 8081 8 | 9 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build 10 | ARG BUILD_CONFIGURATION=Release 11 | WORKDIR /src 12 | COPY ["BookManager.Api.csproj", "./"] 13 | RUN dotnet restore "./BookManager.Api.csproj" 14 | 15 | COPY . . 16 | WORKDIR "/src" 17 | RUN dotnet build "BookManager.Api.csproj" -c $BUILD_CONFIGURATION -o /app/build 18 | 19 | FROM build AS publish 20 | ARG BUILD_CONFIGURATION=Release 21 | RUN dotnet publish "BookManager.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false 22 | 23 | FROM base AS final 24 | WORKDIR /app 25 | COPY --from=publish /app/publish . 26 | ENTRYPOINT ["dotnet", "BookManager.Api.dll"] -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Domain/Book.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | 3 | namespace BookManager.Api.Domain; 4 | 5 | [DynamoDBTable("books")] 6 | public class Book 7 | { 8 | [DynamoDBHashKey("id")] 9 | public Guid Id { get; set; } = Guid.NewGuid(); 10 | [DynamoDBProperty("title")] 11 | public string? Title { get; set; } 12 | [DynamoDBProperty("published_year")] 13 | public int PublishedYear { get; set; } 14 | [DynamoDBProperty("pages")] 15 | public int Pages { get; set; } 16 | [DynamoDBProperty("summary")] 17 | public string? Summary { get; set; } 18 | } -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2; 2 | using Amazon.DynamoDBv2.DataModel; 3 | using BookManager.Api.DTOs; 4 | using BookManager.Api.Services; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | builder.Services.AddEndpointsApiExplorer(); 8 | builder.Services.AddSwaggerGen(); 9 | 10 | // Register DynamoDB client and context 11 | builder.Services.AddAWSService(); 12 | builder.Services.AddScoped(); 13 | 14 | builder.Services.AddTransient(); 15 | 16 | var app = builder.Build(); 17 | if (app.Environment.IsDevelopment()) 18 | { 19 | app.UseSwagger(); 20 | app.UseSwaggerUI(); 21 | } 22 | app.UseHttpsRedirection(); 23 | 24 | app.MapGet("/", () => "Welcome to the Book API!"); 25 | 26 | // Minimal API to get all books 27 | app.MapGet("/books", async (IBookService bookService) => 28 | { 29 | var books = await bookService.GetBooksAsync(); 30 | return Results.Ok(books); 31 | }); 32 | 33 | // Minimal API to get a book by ID 34 | app.MapGet("/books/{id:guid}", async (IBookService bookService, Guid id) => 35 | { 36 | var book = await bookService.GetBookAsync(id); 37 | if (book == null) 38 | { 39 | return Results.NotFound(); 40 | } 41 | return Results.Ok(book); 42 | }); 43 | 44 | // Minimal API to create a new book 45 | app.MapPost("/books", async (IBookService bookService, CreateBookRequest request) => 46 | { 47 | var bookId = await bookService.CreateBookAsync(request); 48 | return Results.Created($"/books/{bookId}", request); 49 | }); 50 | 51 | app.Run(); -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "http": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "swagger", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "dotnetRunMessages": true, 11 | "applicationUrl": "http://localhost:5175" 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | }, 20 | "dotnetRunMessages": true, 21 | "applicationUrl": "https://localhost:7181;http://localhost:5175" 22 | }, 23 | "IIS Express": { 24 | "commandName": "IISExpress", 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "environmentVariables": { 28 | "ASPNETCORE_ENVIRONMENT": "Development" 29 | } 30 | }, 31 | "Container (Dockerfile)": { 32 | "commandName": "Docker", 33 | "launchBrowser": true, 34 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 35 | "environmentVariables": { 36 | "ASPNETCORE_HTTPS_PORTS": "8081", 37 | "ASPNETCORE_HTTP_PORTS": "8080" 38 | }, 39 | "publishAllPorts": true, 40 | "useSSL": true 41 | } 42 | }, 43 | "$schema": "http://json.schemastore.org/launchsettings.json", 44 | "iisSettings": { 45 | "windowsAuthentication": false, 46 | "anonymousAuthentication": true, 47 | "iisExpress": { 48 | "applicationUrl": "http://localhost:38211", 49 | "sslPort": 44301 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | using BookManager.Api.Domain; 3 | using BookManager.Api.DTOs; 4 | 5 | namespace BookManager.Api.Services; 6 | 7 | public class BookService : IBookService 8 | { 9 | private readonly IDynamoDBContext dynamoDBContext; 10 | public BookService(IDynamoDBContext dynamoDBContext) 11 | { 12 | this.dynamoDBContext = dynamoDBContext; 13 | } 14 | 15 | public async Task CreateBookAsync(CreateBookRequest request) 16 | { 17 | var book = new Book() 18 | { 19 | Pages = request.Pages, 20 | Title = request.Title, 21 | Summary = request.Summary, 22 | PublishedYear = request.PublishedYear 23 | }; 24 | await dynamoDBContext.SaveAsync(book); 25 | return book.Id; 26 | } 27 | 28 | public async Task GetBookAsync(Guid id) 29 | { 30 | return await dynamoDBContext.LoadAsync(id); 31 | } 32 | 33 | public async Task> GetBooksAsync() 34 | { 35 | var books = await dynamoDBContext.ScanAsync(new List()).GetRemainingAsync(); 36 | return books; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/Services/IBookService.cs: -------------------------------------------------------------------------------- 1 | using BookManager.Api.Domain; 2 | using BookManager.Api.DTOs; 3 | 4 | namespace BookManager.Api.Services; 5 | 6 | public interface IBookService 7 | { 8 | Task> GetBooksAsync(); 9 | Task GetBookAsync(Guid id); 10 | Task CreateBookAsync(CreateBookRequest request); 11 | } 12 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-ecs-fargate/BookManager.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Data/Product.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | 3 | namespace Products.Api.Data; 4 | 5 | [DynamoDBTable("products")] 6 | public class Product 7 | { 8 | [DynamoDBHashKey("id")] 9 | public string? Id { get; set; } 10 | 11 | [DynamoDBProperty("name")] 12 | public string? Name { get; set; } 13 | 14 | [DynamoDBProperty("price")] 15 | public decimal Price { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Dtos/CreateProductRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Products.Api.Dtos; 2 | 3 | public record CreateProductRequest(string Id, string Name, decimal Price); 4 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Dtos/UpdateProductRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Products.Api.Dtos; 2 | 3 | public record UpdateProductRequest(string Id, string Name, decimal Price); 4 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Products.Api.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Products.Api.http: -------------------------------------------------------------------------------- 1 | @Products.Api_HostAddress = http://localhost:5046 2 | 3 | GET {{Products.Api_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2; 2 | using Amazon.DynamoDBv2.DataModel; 3 | using Products.Api.Dtos; 4 | using Products.Api.Services; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | 8 | // Add services to the container. 9 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 10 | builder.Services.AddEndpointsApiExplorer(); 11 | builder.Services.AddSwaggerGen(); 12 | builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi); 13 | 14 | builder.Services.AddAWSService(); 15 | builder.Services.AddScoped(); 16 | builder.Services.AddTransient(); 17 | 18 | var app = builder.Build(); 19 | 20 | // Configure the HTTP request pipeline. 21 | if (app.Environment.IsDevelopment()) 22 | { 23 | app.UseSwagger(); 24 | app.UseSwaggerUI(); 25 | } 26 | 27 | app.MapPost("/", (CreateProductRequest request, IProductService service) => service.CreateProductAsync(request)); 28 | app.MapGet("/{id}", (string id, IProductService service) => service.GetProductByIdAsync(id)); 29 | app.MapGet("/", (IProductService service) => service.GetAllProductsAsync()); 30 | app.MapDelete("/{id}", (string id, IProductService service) => service.DeleteProductAsync(id)); 31 | app.MapPut("/", (UpdateProductRequest request, IProductService service) => service.UpdateProductAsync(request)); 32 | 33 | 34 | app.UseHttpsRedirection(); 35 | 36 | app.Run(); -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/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:15823", 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:5046", 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:7270;http://localhost:5046", 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 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Services/IProductService.cs: -------------------------------------------------------------------------------- 1 | using Products.Api.Data; 2 | using Products.Api.Dtos; 3 | 4 | namespace Products.Api.Services; 5 | 6 | public interface IProductService 7 | { 8 | public Task CreateProductAsync(CreateProductRequest request); 9 | public Task GetProductByIdAsync(string id); 10 | public Task> GetAllProductsAsync(); 11 | public Task DeleteProductAsync(string id); 12 | public Task UpdateProductAsync(UpdateProductRequest request); 13 | } 14 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/Services/ProductService.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | using Products.Api.Data; 3 | using Products.Api.Dtos; 4 | 5 | namespace Products.Api.Services; 6 | 7 | public class ProductService(IDynamoDBContext ddb) : IProductService 8 | { 9 | public async Task CreateProductAsync(CreateProductRequest request) 10 | { 11 | var product = await ddb.LoadAsync(request.Id); 12 | if (product != null) throw new Exception($"Product with Id {request.Id} Already Exists"); 13 | var productToCreate = new Product() 14 | { 15 | Id = request.Id, 16 | Name = request.Name, 17 | Price = request.Price, 18 | }; 19 | await ddb.SaveAsync(productToCreate); 20 | return productToCreate; 21 | } 22 | 23 | public async Task DeleteProductAsync(string id) 24 | { 25 | var product = await ddb.LoadAsync(id); 26 | if (product == null) throw new Exception($"Product with Id {id} Not Found"); 27 | await ddb.DeleteAsync(product); 28 | } 29 | 30 | public async Task> GetAllProductsAsync() 31 | { 32 | var products = await ddb.ScanAsync(default).GetRemainingAsync(); 33 | return products; 34 | } 35 | 36 | public async Task GetProductByIdAsync(string id) 37 | { 38 | var product = await ddb.LoadAsync(id); 39 | if (product == null) throw new Exception($"Product with Id {id} Not Found"); 40 | return product; 41 | } 42 | 43 | public async Task UpdateProductAsync(UpdateProductRequest request) 44 | { 45 | var product = await ddb.LoadAsync(request.Id); 46 | if (product == null) throw new Exception($"Product with Id {request.Id} Not Found"); 47 | var productToUpdate = new Product() 48 | { 49 | Id = request.Id, 50 | Name = request.Name, 51 | Price = request.Price, 52 | }; 53 | await ddb.SaveAsync(productToUpdate); 54 | return productToUpdate; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/Products.Api/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "profile": "", 3 | "region": "", 4 | "configuration": "Release", 5 | "function-runtime": "dotnet8", 6 | "function-memory-size": 256, 7 | "function-timeout": 30, 8 | "function-handler": "Products.Api", 9 | "function-name": "productapi", 10 | "environment-variables": "ASPNETCORE_ENVIRONMENT=Development;SOMETHING_ELSE=SomeValue", 11 | "function-url-enable": true 12 | } -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/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 | builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi); 8 | 9 | var app = builder.Build(); 10 | 11 | // Configure the HTTP request pipeline. 12 | if (app.Environment.IsDevelopment()) 13 | { 14 | app.UseSwagger(); 15 | app.UseSwaggerUI(); 16 | } 17 | 18 | app.UseHttpsRedirection(); 19 | 20 | var summaries = new[] 21 | { 22 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 23 | }; 24 | 25 | app.MapGet("/weatherforecast", () => 26 | { 27 | var forecast = Enumerable.Range(1, 5).Select(index => 28 | new WeatherForecast 29 | ( 30 | DateOnly.FromDateTime(DateTime.Now.AddDays(index)), 31 | Random.Shared.Next(-20, 55), 32 | summaries[Random.Shared.Next(summaries.Length)] 33 | )) 34 | .ToArray(); 35 | return forecast; 36 | }) 37 | .WithName("GetWeatherForecast") 38 | .WithOpenApi(); 39 | 40 | app.MapGet("/", () => "Hello from AWS Lambda!"); 41 | 42 | app.Run(); 43 | 44 | internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 45 | { 46 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 47 | } 48 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/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:54097", 8 | "sslPort": 44386 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:7097;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 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/SimpleApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/SimpleApi.http: -------------------------------------------------------------------------------- 1 | @SimpleApi_HostAddress = http://localhost:5117 2 | 3 | GET {{SimpleApi_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/SimpleApi/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "profile": "", 3 | "region": "", 4 | "configuration": "Release", 5 | "function-runtime": "dotnet8", 6 | "function-memory-size": 256, 7 | "function-timeout": 30, 8 | "function-handler": "SimpleApi", 9 | "function-name": "simpleapi", 10 | "environment-variables": "ASPNETCORE_ENVIRONMENT=Development;SOMETHING_ELSE=SomeValue", 11 | "function-url-enable": true 12 | } -------------------------------------------------------------------------------- /deploying-aspnet-core-web-api-with-aws-lambda/WebApiOnLambda.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34330.188 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Products.Api", "Products.Api\Products.Api.csproj", "{FE515591-8A8B-4D8F-9A7A-0194677C614E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleApi", "SimpleApi\SimpleApi.csproj", "{CE4A2380-69B8-4871-82E1-AAAB27CC5C05}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {FE515591-8A8B-4D8F-9A7A-0194677C614E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {FE515591-8A8B-4D8F-9A7A-0194677C614E}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {FE515591-8A8B-4D8F-9A7A-0194677C614E}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {FE515591-8A8B-4D8F-9A7A-0194677C614E}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {CE4A2380-69B8-4871-82E1-AAAB27CC5C05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {CE4A2380-69B8-4871-82E1-AAAB27CC5C05}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {CE4A2380-69B8-4871-82E1-AAAB27CC5C05}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {CE4A2380-69B8-4871-82E1-AAAB27CC5C05}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {69831D21-EC03-49B6-B76D-1BE04C644D27} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /dotnet-on-aws-series.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewithmukesh/dotnet-on-aws-series/72e54de7bf3dd8701d7ce0a1440c4f9661349cfe/dotnet-on-aws-series.png -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.6.33815.320 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamoDB.Demo", "DynamoDB.Demo\DynamoDB.Demo.csproj", "{37B2627A-AD42-4BE0-94F0-3F525A82C3C1}" 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 | {37B2627A-AD42-4BE0-94F0-3F525A82C3C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {37B2627A-AD42-4BE0-94F0-3F525A82C3C1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {37B2627A-AD42-4BE0-94F0-3F525A82C3C1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {37B2627A-AD42-4BE0-94F0-3F525A82C3C1}.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 = {D9C2E291-6FCE-4176-A514-1AD47ADD0533} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/Controllers/ProductsController.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace DynamoDB.Demo.Controllers 5 | { 6 | [Route("api/[controller]")] 7 | [ApiController] 8 | public class ProductsController : ControllerBase 9 | { 10 | private readonly IDynamoDBContext _context; 11 | 12 | public ProductsController(IDynamoDBContext context) 13 | { 14 | _context = context; 15 | } 16 | 17 | [HttpGet("{id}/{barcode}")] 18 | public async Task Get(string id, string barcode) 19 | { 20 | var product = await _context.LoadAsync(id, barcode); 21 | if (product == null) return NotFound(); 22 | return Ok(product); 23 | } 24 | 25 | [HttpGet] 26 | public async Task GetAll() 27 | { 28 | var products = await _context.ScanAsync(default).GetRemainingAsync(); 29 | return Ok(products); 30 | } 31 | 32 | [HttpPost] 33 | public async Task Create(Product request) 34 | { 35 | var product = await _context.LoadAsync(request.Id, request.Barcode); 36 | if (product != null) return BadRequest($"Product with Id {request.Id} and BarCode {request.Barcode} Already Exists"); 37 | await _context.SaveAsync(request); 38 | return Ok(request); 39 | } 40 | 41 | [HttpDelete("{id}/{barcode}")] 42 | public async Task Delete(string id, string barcode) 43 | { 44 | var product = await _context.LoadAsync(id, barcode); 45 | if (product == null) return NotFound(); 46 | await _context.DeleteAsync(product); 47 | return NoContent(); 48 | } 49 | 50 | [HttpPut] 51 | public async Task Update(Product request) 52 | { 53 | var product = await _context.LoadAsync(request.Id, request.Barcode); 54 | if (product == null) return NotFound(); 55 | await _context.SaveAsync(request); 56 | return Ok(request); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/DynamoDB.Demo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/Product.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2.DataModel; 2 | 3 | namespace DynamoDB.Demo; 4 | 5 | [DynamoDBTable("products")] 6 | public class Product 7 | { 8 | [DynamoDBHashKey("id")] 9 | public string? Id { get; set; } 10 | [DynamoDBRangeKey("barcode")] 11 | public string? Barcode { get; set; } 12 | [DynamoDBProperty("name")] 13 | public string? Name { get; set; } 14 | [DynamoDBProperty("description")] 15 | public string? Description { get; set; } 16 | [DynamoDBProperty("price")] 17 | public decimal Price { get; set; } 18 | } 19 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.DynamoDBv2; 2 | using Amazon.DynamoDBv2.DataModel; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | // Add services to the container. 7 | 8 | builder.Services.AddControllers(); 9 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 10 | builder.Services.AddEndpointsApiExplorer(); 11 | builder.Services.AddSwaggerGen(); 12 | 13 | var awsOptions = builder.Configuration.GetAWSOptions(); 14 | builder.Services.AddDefaultAWSOptions(awsOptions); 15 | builder.Services.AddAWSService(); 16 | builder.Services.AddScoped(); 17 | 18 | var app = builder.Build(); 19 | 20 | // Configure the HTTP request pipeline. 21 | if (app.Environment.IsDevelopment()) 22 | { 23 | app.UseSwagger(); 24 | app.UseSwaggerUI(); 25 | } 26 | 27 | app.UseHttpsRedirection(); 28 | 29 | app.UseAuthorization(); 30 | 31 | app.MapControllers(); 32 | 33 | app.Run(); 34 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "https": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "swagger", 9 | "applicationUrl": "https://localhost:7032;http://localhost:5070", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /dynamodb-dotnet-7-webapi/DynamoDB.Demo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "AWS": { 10 | "Profile": "default", 11 | "Region": "ap-south-1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md 26 | !**/.gitignore 27 | !.git/HEAD 28 | !.git/config 29 | !.git/packed-refs 30 | !.git/refs/heads/** -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35027.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookManager.Api", "BookManager.Api\BookManager.Api.csproj", "{59F0A5C3-D417-4C5F-8C76-114795B72E41}" 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 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {59F0A5C3-D417-4C5F-8C76-114795B72E41}.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 = {F75518C1-E8FB-4F3B-9440-DEE6237D8E12} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/AppDbContext.cs: -------------------------------------------------------------------------------- 1 | using BookManager.Api.Domain; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace BookManager.Api; 5 | 6 | public class AppDbContext : DbContext 7 | { 8 | public DbSet Books { get; set; } 9 | public AppDbContext(DbContextOptions options) : base(options) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/BookManager.Api.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | book-manager 11 | DefaultContainer 12 | 1.0;latest 13 | 14 | 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/BookManager.Api.http: -------------------------------------------------------------------------------- 1 | @BookManager.Api_HostAddress = http://localhost:5175 2 | 3 | GET {{BookManager.Api_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/BookManager.Api.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}") = "BookManager.Api", "BookManager.Api.csproj", "{464E25C5-5346-4B7C-A6F2-52DB14A71F01}" 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 | {464E25C5-5346-4B7C-A6F2-52DB14A71F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {464E25C5-5346-4B7C-A6F2-52DB14A71F01}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {464E25C5-5346-4B7C-A6F2-52DB14A71F01}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {464E25C5-5346-4B7C-A6F2-52DB14A71F01}.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 = {7E1C4075-7FC0-4DB1-9335-CD058D066A55} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/DTOs/CreateBookRequest.cs: -------------------------------------------------------------------------------- 1 | namespace BookManager.Api.DTOs; 2 | 3 | public record CreateBookRequest(string Title, int PublishedYear, int Pages, string Summary); -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Domain/Book.cs: -------------------------------------------------------------------------------- 1 | namespace BookManager.Api.Domain; 2 | 3 | public class Book 4 | { 5 | public Guid Id { get; set; } = Guid.NewGuid(); 6 | public string? Title { get; set; } 7 | public int PublishedYear { get; set; } 8 | public int Pages { get; set; } 9 | public string? Summary { get; set; } 10 | } -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Migrations/20241014011119_Initial.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using BookManager.Api; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; 9 | 10 | #nullable disable 11 | 12 | namespace BookManager.Api.Migrations 13 | { 14 | [DbContext(typeof(AppDbContext))] 15 | [Migration("20241014011119_Initial")] 16 | partial class Initial 17 | { 18 | /// 19 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 20 | { 21 | #pragma warning disable 612, 618 22 | modelBuilder 23 | .HasAnnotation("ProductVersion", "8.0.10") 24 | .HasAnnotation("Relational:MaxIdentifierLength", 63); 25 | 26 | NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); 27 | 28 | modelBuilder.Entity("BookManager.Api.Domain.Book", b => 29 | { 30 | b.Property("Id") 31 | .ValueGeneratedOnAdd() 32 | .HasColumnType("uuid"); 33 | 34 | b.Property("Pages") 35 | .HasColumnType("integer"); 36 | 37 | b.Property("PublishedYear") 38 | .HasColumnType("integer"); 39 | 40 | b.Property("Summary") 41 | .HasColumnType("text"); 42 | 43 | b.Property("Title") 44 | .HasColumnType("text"); 45 | 46 | b.HasKey("Id"); 47 | 48 | b.ToTable("Books"); 49 | }); 50 | #pragma warning restore 612, 618 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Migrations/20241014011119_Initial.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | #nullable disable 5 | 6 | namespace BookManager.Api.Migrations 7 | { 8 | /// 9 | public partial class Initial : Migration 10 | { 11 | /// 12 | protected override void Up(MigrationBuilder migrationBuilder) 13 | { 14 | migrationBuilder.CreateTable( 15 | name: "Books", 16 | columns: table => new 17 | { 18 | Id = table.Column(type: "uuid", nullable: false), 19 | Title = table.Column(type: "text", nullable: true), 20 | PublishedYear = table.Column(type: "integer", nullable: false), 21 | Pages = table.Column(type: "integer", nullable: false), 22 | Summary = table.Column(type: "text", nullable: true) 23 | }, 24 | constraints: table => 25 | { 26 | table.PrimaryKey("PK_Books", x => x.Id); 27 | }); 28 | } 29 | 30 | /// 31 | protected override void Down(MigrationBuilder migrationBuilder) 32 | { 33 | migrationBuilder.DropTable( 34 | name: "Books"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Migrations/AppDbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using BookManager.Api; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; 8 | 9 | #nullable disable 10 | 11 | namespace BookManager.Api.Migrations 12 | { 13 | [DbContext(typeof(AppDbContext))] 14 | partial class AppDbContextModelSnapshot : ModelSnapshot 15 | { 16 | protected override void BuildModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "8.0.10") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 63); 22 | 23 | NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); 24 | 25 | modelBuilder.Entity("BookManager.Api.Domain.Book", b => 26 | { 27 | b.Property("Id") 28 | .ValueGeneratedOnAdd() 29 | .HasColumnType("uuid"); 30 | 31 | b.Property("Pages") 32 | .HasColumnType("integer"); 33 | 34 | b.Property("PublishedYear") 35 | .HasColumnType("integer"); 36 | 37 | b.Property("Summary") 38 | .HasColumnType("text"); 39 | 40 | b.Property("Title") 41 | .HasColumnType("text"); 42 | 43 | b.HasKey("Id"); 44 | 45 | b.ToTable("Books"); 46 | }); 47 | #pragma warning restore 612, 618 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using BookManager.Api; 2 | using BookManager.Api.DTOs; 3 | using BookManager.Api.Services; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | builder.Services.AddEndpointsApiExplorer(); 8 | builder.Services.AddSwaggerGen(); 9 | 10 | builder.Services.AddTransient(); 11 | 12 | var assemblyName = typeof(Program).Assembly.GetName().Name; 13 | var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); 14 | 15 | builder.Services.AddDbContext( 16 | c => c.UseNpgsql(connectionString, m => m.MigrationsAssembly(assemblyName))); 17 | var app = builder.Build(); 18 | 19 | if (app.Environment.IsDevelopment()) 20 | { 21 | app.UseSwagger(); 22 | app.UseSwaggerUI(); 23 | } 24 | app.UseHttpsRedirection(); 25 | 26 | app.MapGet("/", () => "Welcome to the Book API!"); 27 | 28 | // Minimal API to get all books 29 | app.MapGet("/books", async (IBookService bookService) => 30 | { 31 | var books = await bookService.GetBooksAsync(); 32 | return Results.Ok(books); 33 | }); 34 | 35 | // Minimal API to get a book by ID 36 | app.MapGet("/books/{id:guid}", async (IBookService bookService, Guid id) => 37 | { 38 | var book = await bookService.GetBookAsync(id); 39 | if (book == null) 40 | { 41 | return Results.NotFound(); 42 | } 43 | return Results.Ok(book); 44 | }); 45 | 46 | // Minimal API to create a new book 47 | app.MapPost("/books", async (IBookService bookService, CreateBookRequest request) => 48 | { 49 | var bookId = await bookService.CreateBookAsync(request); 50 | return Results.Created($"/books/{bookId}", request); 51 | }); 52 | 53 | using var scope = app.Services.CreateScope(); 54 | var context = scope.ServiceProvider.GetRequiredService(); 55 | if (context.Database.GetPendingMigrations().Any()) 56 | { 57 | await context.Database.MigrateAsync(); 58 | } 59 | 60 | app.Run(); -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "http": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "swagger", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "dotnetRunMessages": true, 11 | "applicationUrl": "http://localhost:5175" 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | }, 20 | "dotnetRunMessages": true, 21 | "applicationUrl": "https://localhost:7181;http://localhost:5175" 22 | } 23 | }, 24 | "$schema": "http://json.schemastore.org/launchsettings.json" 25 | } -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Services/BookService.cs: -------------------------------------------------------------------------------- 1 | using BookManager.Api.Domain; 2 | using BookManager.Api.DTOs; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace BookManager.Api.Services; 6 | 7 | public class BookService(AppDbContext dbContext) : IBookService 8 | { 9 | public async Task CreateBookAsync(CreateBookRequest request) 10 | { 11 | var book = new Book() 12 | { 13 | Pages = request.Pages, 14 | Title = request.Title, 15 | Summary = request.Summary, 16 | PublishedYear = request.PublishedYear 17 | }; 18 | await dbContext.AddAsync(book); 19 | await dbContext.SaveChangesAsync(); 20 | return book.Id; 21 | } 22 | 23 | public async Task GetBookAsync(Guid id) 24 | { 25 | var book = await dbContext.Books.FindAsync(id); 26 | return book ?? null; 27 | } 28 | 29 | public async Task> GetBooksAsync() 30 | { 31 | var books = await dbContext.Books.ToListAsync(); 32 | return books; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/Services/IBookService.cs: -------------------------------------------------------------------------------- 1 | using BookManager.Api.Domain; 2 | using BookManager.Api.DTOs; 3 | 4 | namespace BookManager.Api.Services; 5 | 6 | public interface IBookService 7 | { 8 | Task> GetBooksAsync(); 9 | Task GetBookAsync(Guid id); 10 | Task CreateBookAsync(CreateBookRequest request); 11 | } 12 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "ConnectionStrings": { 9 | "DefaultConnection": "Server=localhost;Port=5432;Database=identityDb;User Id=postgres;Password=admin" 10 | } 11 | } -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/appsettings.Docker.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=postgres;Port=5432;Database=identityDb;User Id=postgres;Password=admin" 4 | } 5 | } -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/BookManager.Api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | name: book-manager 3 | 4 | services: 5 | api: 6 | container_name: book-manager 7 | image: book-manager:latest 8 | environment: 9 | - ASPNETCORE_ENVIRONMENT=Docker 10 | - ASPNETCORE_URLS=http://+:8080 11 | ports: 12 | - 8080:8080 13 | depends_on: 14 | postgres: 15 | condition: service_healthy 16 | postgres: 17 | container_name: postgres 18 | image: postgres:17-alpine 19 | environment: 20 | - POSTGRES_USER=postgres 21 | - POSTGRES_PASSWORD=admin 22 | ports: 23 | - 5432:5432 24 | volumes: 25 | - postgres-data:/data/db 26 | healthcheck: 27 | test: ["CMD-SHELL", "pg_isready -U postgres"] 28 | interval: 10s 29 | timeout: 5s 30 | retries: 5 31 | volumes: 32 | postgres-data: 33 | -------------------------------------------------------------------------------- /hosting-aspnet-core-webapi-on-amazon-ec2/user-script.md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit immediately if a command exits with a non-zero status 3 | 4 | # Update the package index 5 | 6 | sudo yum update -y 7 | 8 | # Install Git 9 | 10 | sudo yum install -y git 11 | 12 | # Install .NET SDK 8.0 13 | 14 | sudo yum install -y dotnet-sdk-8.0 15 | 16 | # Install Docker 17 | 18 | sudo yum install -y docker 19 | 20 | # Start and enable Docker service 21 | 22 | sudo systemctl start docker 23 | sudo systemctl enable docker 24 | 25 | # Install Docker Compose 26 | 27 | sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose 28 | sudo chmod +x /usr/local/bin/docker-compose 29 | 30 | # Optional: Verify installations 31 | 32 | echo "Verifying installations..." 33 | dotnet --version 34 | docker --version 35 | docker-compose --version 36 | -------------------------------------------------------------------------------- /lambda-authorizer/HelloWorld/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.APIGatewayEvents; 2 | using Amazon.Lambda.Core; 3 | 4 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 5 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 6 | 7 | namespace HelloWorld; 8 | 9 | public class Function 10 | { 11 | 12 | /// 13 | /// A simple function that takes a string and does a ToUpper 14 | /// 15 | /// 16 | /// 17 | /// 18 | public string FunctionHandler(APIGatewayHttpApiV2ProxyRequest context) 19 | { 20 | return "hello world"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lambda-authorizer/HelloWorld/HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /lambda-authorizer/HelloWorld/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /lambda-authorizer/HelloWorld/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "HelloWorld/test/HelloWorld.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "HelloWorld/src/HelloWorld" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /lambda-authorizer/HelloWorld/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "HelloWorld::HelloWorld.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "hello-world", 19 | "package-type" : "Zip", 20 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_hello-world", 21 | "function-subnets" : "", 22 | "function-security-groups" : "", 23 | "tracing-mode" : "PassThrough", 24 | "environment-variables" : "", 25 | "image-tag" : "" 26 | } -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuth/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.APIGatewayEvents; 2 | using Amazon.Lambda.Core; 3 | using Microsoft.IdentityModel.Tokens; 4 | using System.IdentityModel.Tokens.Jwt; 5 | using System.Security.Claims; 6 | using System.Text; 7 | using System.Text.Json; 8 | 9 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 10 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 11 | 12 | namespace LambdaAuth; 13 | 14 | public class Function 15 | { 16 | 17 | private const string key = "S0M3RAN0MS3CR3T!1!MAG1C!1!12345678"; 18 | public APIGatewayCustomAuthorizerV2IamResponse FunctionHandler(APIGatewayCustomAuthorizerV2Request request) 19 | { 20 | Console.WriteLine(JsonSerializer.Serialize(request)); 21 | var authToken = request.Headers["authorization"]; 22 | var claimsPrincipal = GetClaimsPrincipal(authToken); 23 | var effect = "Deny"; 24 | var principalId = "unauthorized"; 25 | if (claimsPrincipal is not null) 26 | { 27 | effect = "Allow"; 28 | principalId = claimsPrincipal?.FindFirst(ClaimTypes.Name)?.Value; 29 | } 30 | return new APIGatewayCustomAuthorizerV2IamResponse() 31 | { 32 | PrincipalID = principalId, 33 | PolicyDocument = new APIGatewayCustomAuthorizerPolicy() 34 | { 35 | Statement = new List 36 | { 37 | new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement() 38 | { 39 | Effect = effect, 40 | Resource = new HashSet { request.RouteArn }, 41 | Action = new HashSet { "execute-api:Invoke" } 42 | } 43 | } 44 | } 45 | }; 46 | } 47 | private ClaimsPrincipal GetClaimsPrincipal(string authToken) 48 | { 49 | var tokenHandler = new JwtSecurityTokenHandler(); 50 | var validationParams = new TokenValidationParameters() 51 | { 52 | ValidateLifetime = true, 53 | ValidateAudience = false, 54 | ValidateIssuer = false, 55 | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)), 56 | }; 57 | try 58 | { 59 | return tokenHandler.ValidateToken(authToken, validationParams, out SecurityToken securityToken); 60 | } 61 | catch 62 | { 63 | return null; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuth/LambdaAuth.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuth/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuth/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "LambdaAuth/test/LambdaAuth.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "LambdaAuth/src/LambdaAuth" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuth/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "LambdaAuth::LambdaAuth.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "lambda-auth", 19 | "package-type" : "Zip", 20 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_hello-world", 21 | "function-subnets" : "", 22 | "function-security-groups" : "", 23 | "tracing-mode" : "PassThrough", 24 | "environment-variables" : "", 25 | "image-tag" : "" 26 | } -------------------------------------------------------------------------------- /lambda-authorizer/LambdaAuthorizer.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34330.188 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "HelloWorld\HelloWorld.csproj", "{8C6301C1-1E3A-4FE9-AFB5-533C10FB22E7}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokenGeneration", "TokenGeneration\TokenGeneration.csproj", "{F74F9364-C2A6-470B-87FA-E735E9B4E348}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LambdaAuth", "LambdaAuth\LambdaAuth.csproj", "{B2B54932-4DCA-4B18-8318-61AFED47ED7D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {8C6301C1-1E3A-4FE9-AFB5-533C10FB22E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {8C6301C1-1E3A-4FE9-AFB5-533C10FB22E7}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {8C6301C1-1E3A-4FE9-AFB5-533C10FB22E7}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {8C6301C1-1E3A-4FE9-AFB5-533C10FB22E7}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {F74F9364-C2A6-470B-87FA-E735E9B4E348}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {F74F9364-C2A6-470B-87FA-E735E9B4E348}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {F74F9364-C2A6-470B-87FA-E735E9B4E348}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {F74F9364-C2A6-470B-87FA-E735E9B4E348}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {B2B54932-4DCA-4B18-8318-61AFED47ED7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {B2B54932-4DCA-4B18-8318-61AFED47ED7D}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {B2B54932-4DCA-4B18-8318-61AFED47ED7D}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {B2B54932-4DCA-4B18-8318-61AFED47ED7D}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {38FFD4FE-62C6-4799-AF52-9584BD64AB5B} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /lambda-authorizer/TokenGeneration/Function.cs: -------------------------------------------------------------------------------- 1 | using Amazon.Lambda.APIGatewayEvents; 2 | using Amazon.Lambda.Core; 3 | using Microsoft.IdentityModel.Tokens; 4 | using System.IdentityModel.Tokens.Jwt; 5 | using System.Security.Claims; 6 | using System.Text; 7 | 8 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 9 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 10 | 11 | namespace TokenGeneration; 12 | 13 | public class Function 14 | { 15 | 16 | private const string key = "S0M3RAN0MS3CR3T!1!MAG1C!1!12345678"; 17 | public string FunctionHandler(APIGatewayHttpApiV2ProxyRequest request) 18 | { 19 | var user = new 20 | { 21 | Name = "Mukesh", 22 | Email = "hello@codewithmukesh.com" 23 | }; 24 | var claims = new List { 25 | new(ClaimTypes.Email, user.Email), 26 | new(ClaimTypes.Name, user.Name) 27 | }; 28 | byte[] secret = Encoding.UTF8.GetBytes(key); 29 | var signingCredentials = new SigningCredentials( 30 | new SymmetricSecurityKey(secret), 31 | SecurityAlgorithms.HmacSha256); 32 | var token = new JwtSecurityToken( 33 | claims: claims, 34 | expires: DateTime.UtcNow.AddMinutes(5), 35 | signingCredentials: signingCredentials); 36 | var tokenHandler = new JwtSecurityTokenHandler(); 37 | return tokenHandler.WriteToken(token); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lambda-authorizer/TokenGeneration/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Mock Lambda Test Tool": { 4 | "commandName": "Executable", 5 | "commandLineArgs": "--port 5050", 6 | "workingDirectory": ".\\bin\\$(Configuration)\\net6.0", 7 | "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /lambda-authorizer/TokenGeneration/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "TokenGeneration/test/TokenGeneration.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "TokenGeneration/src/TokenGeneration" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /lambda-authorizer/TokenGeneration/TokenGeneration.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | enable 5 | enable 6 | true 7 | Lambda 8 | 9 | true 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lambda-authorizer/TokenGeneration/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Information" : [ 4 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 5 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 6 | "dotnet lambda help", 7 | "All the command line options for the Lambda command can be specified in this file." 8 | ], 9 | "profile" : "default", 10 | "region" : "ap-south-1", 11 | "configuration" : "Release", 12 | "function-architecture" : "x86_64", 13 | "function-runtime" : "dotnet6", 14 | "function-memory-size" : 256, 15 | "function-timeout" : 30, 16 | "function-handler" : "TokenGeneration::TokenGeneration.Function::FunctionHandler", 17 | "framework" : "net6.0", 18 | "function-name" : "token-generation", 19 | "package-type" : "Zip", 20 | "function-role" : "arn:aws:iam::821175633958:role/lambda_exec_hello-world", 21 | "function-subnets" : "", 22 | "function-security-groups" : "", 23 | "tracing-mode" : "PassThrough", 24 | "environment-variables" : "", 25 | "image-tag" : "" 26 | } -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Controllers/BucketsController.cs: -------------------------------------------------------------------------------- 1 | using Amazon.S3; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace S3.Demo.API.Controllers 5 | { 6 | [Route("api/[controller]")] 7 | [ApiController] 8 | public class BucketsController : ControllerBase 9 | { 10 | private readonly IAmazonS3 _s3Client; 11 | 12 | public BucketsController(IAmazonS3 s3Client) 13 | { 14 | _s3Client = s3Client; 15 | } 16 | 17 | 18 | [HttpPost] 19 | public async Task CreateBucketAsync(string bucketName) 20 | { 21 | var bucketExists = await Amazon.S3.Util.AmazonS3Util.DoesS3BucketExistV2Async(_s3Client, bucketName); 22 | if (bucketExists) return BadRequest($"Bucket {bucketName} already exists."); 23 | await _s3Client.PutBucketAsync(bucketName); 24 | return Created("buckets", $"Bucket {bucketName} created."); 25 | } 26 | 27 | [HttpGet] 28 | public async Task GetAllBucketAsync() 29 | { 30 | var data = await _s3Client.ListBucketsAsync(); 31 | var buckets = data.Buckets.Select(b => { return b.BucketName; }); 32 | return Ok(buckets); 33 | } 34 | 35 | [HttpDelete] 36 | public async Task DeleteBucketAsync(string bucketName) 37 | { 38 | await _s3Client.DeleteBucketAsync(bucketName); 39 | return NoContent(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Controllers/FilesController.cs: -------------------------------------------------------------------------------- 1 | using Amazon.S3; 2 | using Amazon.S3.Model; 3 | using Microsoft.AspNetCore.Mvc; 4 | using S3.Demo.API.Models; 5 | 6 | namespace S3.Demo.API.Controllers 7 | { 8 | [Route("api/[controller]")] 9 | [ApiController] 10 | public class FilesController : ControllerBase 11 | { 12 | private readonly IAmazonS3 _s3Client; 13 | 14 | public FilesController(IAmazonS3 s3Client) 15 | { 16 | _s3Client = s3Client; 17 | } 18 | 19 | 20 | [HttpPost] 21 | public async Task UploadFileAsync(IFormFile file, string bucketName, string? prefix) 22 | { 23 | var bucketExists = await Amazon.S3.Util.AmazonS3Util.DoesS3BucketExistV2Async(_s3Client, bucketName); 24 | if (!bucketExists) return NotFound($"Bucket {bucketName} does not exist."); 25 | var request = new PutObjectRequest() 26 | { 27 | BucketName = bucketName, 28 | Key = string.IsNullOrEmpty(prefix) ? file.FileName : $"{prefix?.TrimEnd('/')}/{file.FileName}", 29 | InputStream = file.OpenReadStream() 30 | }; 31 | request.Metadata.Add("Content-Type", file.ContentType); 32 | await _s3Client.PutObjectAsync(request); 33 | return Ok($"File {prefix}/{file.FileName} uploaded to S3 successfully!"); 34 | } 35 | 36 | [HttpGet] 37 | public async Task GetAllFilesAsync(string bucketName, string? prefix) 38 | { 39 | var bucketExists = await Amazon.S3.Util.AmazonS3Util.DoesS3BucketExistV2Async(_s3Client, bucketName); 40 | if (!bucketExists) return NotFound($"Bucket {bucketName} does not exist."); 41 | var request = new ListObjectsV2Request() 42 | { 43 | BucketName = bucketName, 44 | Prefix = prefix 45 | }; 46 | var result = await _s3Client.ListObjectsV2Async(request); 47 | var s3Objects = result.S3Objects.Select(s => 48 | { 49 | var urlRequest = new GetPreSignedUrlRequest() 50 | { 51 | BucketName = bucketName, 52 | Key = s.Key, 53 | Expires = DateTime.UtcNow.AddMinutes(1) 54 | }; 55 | return new S3ObjectDto() 56 | { 57 | Name = s.Key.ToString(), 58 | PresignedUrl = _s3Client.GetPreSignedURL(urlRequest), 59 | }; 60 | }); 61 | return Ok(s3Objects); 62 | } 63 | 64 | [HttpGet("preview")] 65 | public async Task GetFileByKeyAsync(string bucketName, string key) 66 | { 67 | var bucketExists = await Amazon.S3.Util.AmazonS3Util.DoesS3BucketExistV2Async(_s3Client, bucketName); 68 | if (!bucketExists) return NotFound($"Bucket {bucketName} does not exist."); 69 | var s3Object = await _s3Client.GetObjectAsync(bucketName, key); 70 | return File(s3Object.ResponseStream, s3Object.Headers.ContentType); 71 | } 72 | 73 | [HttpDelete] 74 | public async Task DeleteFileAsync(string bucketName, string key) 75 | { 76 | var bucketExists = await Amazon.S3.Util.AmazonS3Util.DoesS3BucketExistV2Async(_s3Client, bucketName); 77 | if (!bucketExists) return NotFound($"Bucket {bucketName} does not exist"); 78 | await _s3Client.DeleteObjectAsync(bucketName, key); 79 | return NoContent(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace S3.Demo.API.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet(Name = "GetWeatherForecast")] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Models/S3ObjectDto.cs: -------------------------------------------------------------------------------- 1 | namespace S3.Demo.API.Models 2 | { 3 | public class S3ObjectDto 4 | { 5 | public string? Name { get; set; } 6 | public string? PresignedUrl { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.S3; 2 | 3 | var builder = WebApplication.CreateBuilder(args); 4 | 5 | // Add services to the container. 6 | 7 | builder.Services.AddControllers(); 8 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 9 | builder.Services.AddEndpointsApiExplorer(); 10 | builder.Services.AddSwaggerGen(); 11 | builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions()); 12 | builder.Services.AddAWSService(); 13 | var app = builder.Build(); 14 | 15 | // Configure the HTTP request pipeline. 16 | if (app.Environment.IsDevelopment()) 17 | { 18 | app.UseSwagger(); 19 | app.UseSwaggerUI(); 20 | } 21 | 22 | app.UseHttpsRedirection(); 23 | 24 | app.UseAuthorization(); 25 | 26 | app.MapControllers(); 27 | 28 | app.Run(); 29 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:45745", 8 | "sslPort": 44316 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5222", 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:7084;http://localhost:5222", 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 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/S3.Demo.API.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace S3.Demo.API 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateOnly Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string? Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "AWS": { 10 | "Profile": "default", 11 | "Region": "ap-south-1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /s3-dotnet-7-webapi/S3.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S3.Demo.API", "S3.Demo.API\S3.Demo.API.csproj", "{F0B8B544-3A18-49AB-8A63-794202749294}" 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 | {F0B8B544-3A18-49AB-8A63-794202749294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F0B8B544-3A18-49AB-8A63-794202749294}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F0B8B544-3A18-49AB-8A63-794202749294}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F0B8B544-3A18-49AB-8A63-794202749294}.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 = {D2A11929-7669-4EB2-A2AA-1CC2895CFE27} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35707.178 d17.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SESDemo", "SESDemo\SESDemo.csproj", "{4E3CA2A6-3529-41BD-8A31-48084DED8F91}" 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 | {4E3CA2A6-3529-41BD-8A31-48084DED8F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4E3CA2A6-3529-41BD-8A31-48084DED8F91}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4E3CA2A6-3529-41BD-8A31-48084DED8F91}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4E3CA2A6-3529-41BD-8A31-48084DED8F91}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Models/MailOptions.cs: -------------------------------------------------------------------------------- 1 | namespace SESDemo.Models; 2 | 3 | public class MailOptions 4 | { 5 | public string? Host { get; set; } 6 | public int Port { get; set; } 7 | public string? DisplayName { get; set; } 8 | public string? Mail { get; set; } 9 | public string? Username { get; set; } 10 | public string? Password { get; set; } 11 | } -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Models/MailRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SESDemo.Models; 2 | 3 | public class MailRequest 4 | { 5 | public string? Recepient { get; set; } 6 | public string? Subject { get; set; } 7 | public string? Body { get; set; } 8 | } -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SimpleEmail; 2 | using SESDemo.Models; 3 | using SESDemo.Services; 4 | 5 | var builder = WebApplication.CreateBuilder(args); 6 | builder.Services.AddEndpointsApiExplorer(); 7 | builder.Services.AddSwaggerGen(); 8 | 9 | builder.Services.Configure(builder.Configuration.GetSection("MailOptions")); 10 | builder.Services.AddKeyedTransient("smtp"); 11 | 12 | builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions()); 13 | builder.Services.AddAWSService(); 14 | builder.Services.AddKeyedTransient("sdk"); 15 | 16 | var app = builder.Build(); 17 | 18 | if (app.Environment.IsDevelopment()) 19 | { 20 | app.UseSwagger(); 21 | app.UseSwaggerUI(); 22 | } 23 | 24 | app.MapPost("/mail/{type}", (IServiceProvider provider, string type, MailRequest request) => 25 | { 26 | var service = provider.GetKeyedService(type); 27 | if (service != null) 28 | service.SendEmailAsync(request); 29 | }); 30 | 31 | app.UseHttpsRedirection(); 32 | app.Run(); -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/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:34581", 8 | "sslPort": 44380 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5102", 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:7202;http://localhost:5102", 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 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/SESDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/SESDemo.http: -------------------------------------------------------------------------------- 1 | @SESDemo_HostAddress = http://localhost:5102 2 | 3 | GET {{SESDemo_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Services/IEmailService.cs: -------------------------------------------------------------------------------- 1 | using SESDemo.Models; 2 | 3 | namespace SESDemo.Services; 4 | 5 | public interface IEmailService 6 | { 7 | Task SendEmailAsync(MailRequest mailRequest); 8 | } 9 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Services/SdkEmailService.cs: -------------------------------------------------------------------------------- 1 | using Amazon.SimpleEmail; 2 | using Amazon.SimpleEmail.Model; 3 | using Microsoft.Extensions.Options; 4 | using SESDemo.Models; 5 | 6 | namespace SESDemo.Services; 7 | 8 | public class SdkEmailService : IEmailService 9 | { 10 | private readonly MailOptions _mailOptions; 11 | private readonly IAmazonSimpleEmailService _mailService; 12 | public SdkEmailService(IOptions mailOptions, 13 | IAmazonSimpleEmailService mailService) 14 | { 15 | _mailOptions = mailOptions.Value; 16 | _mailService = mailService; 17 | } 18 | public async Task SendEmailAsync(MailRequest mailRequest) 19 | { 20 | var mailBody = new Body(new Content(mailRequest.Body)); 21 | var message = new Message(new Content(mailRequest.Subject), mailBody); 22 | var destination = new Destination(new List { mailRequest.Recepient! }); 23 | var request = new SendEmailRequest(_mailOptions.Mail, destination, message); 24 | await _mailService.SendEmailAsync(request); 25 | } 26 | } -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/Services/SmtpEmailService.cs: -------------------------------------------------------------------------------- 1 | using MailKit.Net.Smtp; 2 | using MailKit.Security; 3 | using Microsoft.Extensions.Options; 4 | using MimeKit; 5 | using SESDemo.Models; 6 | 7 | namespace SESDemo.Services; 8 | 9 | public class SmtpEmailService : IEmailService 10 | { 11 | private readonly MailOptions _mailOptions; 12 | public SmtpEmailService(IOptions mailOptions) 13 | { 14 | _mailOptions = mailOptions.Value; 15 | } 16 | public async Task SendEmailAsync(MailRequest mailRequest) 17 | { 18 | var email = new MimeMessage(); 19 | email.From.Add(new MailboxAddress(_mailOptions.DisplayName, _mailOptions.Mail)); 20 | email.To.Add(MailboxAddress.Parse(mailRequest.Recepient)); 21 | email.Subject = mailRequest.Subject; 22 | var builder = new BodyBuilder(); 23 | builder.HtmlBody = mailRequest.Body; 24 | email.Body = builder.ToMessageBody(); 25 | using var smtp = new SmtpClient(); 26 | smtp.Connect(_mailOptions.Host, _mailOptions.Port, SecureSocketOptions.StartTls); 27 | smtp.Authenticate(_mailOptions.Username, _mailOptions.Password); 28 | await smtp.SendAsync(email); 29 | smtp.Disconnect(true); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /send-emails-from-dotnet-using-amazon-ses/SESDemo/SESDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "MailOptions": { 10 | "Host": "email-smtp.us-east-1.amazonaws.com", 11 | "Port": 587, 12 | "DisplayName": "Mukesh Murugan", 13 | "Mail": "verfied_email", 14 | "Username": "username", 15 | "Password": "password" 16 | } 17 | } 18 | --------------------------------------------------------------------------------