├── .devcontainer ├── dotnet │ └── devcontainer.json └── slides │ └── devcontainer.json ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── dotnetversionsweeper.yml │ └── marp-pages.yml ├── .gitignore ├── .markdownlint.json ├── .vscode └── settings.json ├── 00-basic-console-template ├── BasicConsoleSample.csproj └── Program.cs ├── 01-console-configuration-json ├── ConsoleConfigurationJson.csproj ├── Program.cs └── config.json ├── 02-console-configuration-environment ├── ConsoleConfigurationEnv.csproj ├── Program.cs └── config.json ├── 03-console-configuration-cmdline ├── ConsoleConfigurationCmd.csproj ├── Program.cs └── config.json ├── 04-console-configuration-user-secrets ├── ConsoleConfigurationUserSecrets.csproj ├── Program.cs └── config.json ├── 05-console-configuration-in-memory ├── ConsoleConfigurationInMem.csproj ├── Program.cs └── config.json ├── 06-console-config-sections ├── ConsoleConfigSections.csproj ├── Program.cs └── config.json ├── 06b-console-config-sections-cmdline-mappings ├── ConsoleConfigSectionMappings.csproj ├── Program.cs └── config.json ├── 07-console-key-per-file ├── ConsoleConfigurationKeys.csproj ├── Program.cs ├── config.json └── keyPerFile │ ├── Logging__KeyFile │ ├── SecretKey │ ├── environment │ └── greeting ├── 08-console-keyvault ├── ConsoleKeyvault.csproj ├── Program.cs ├── appsettings.Development.json ├── appsettings.json └── setup.sh ├── 09-hosted-console-template ├── HostedConsoleTemplate.csproj ├── Program.cs └── appsettings.json ├── 09b-alternate-hosted-template ├── AltHostedConsoleTemplate.csproj ├── Program.cs └── appsettings.json ├── 09c-indexer-api ├── IndexerApi.csproj ├── Program.cs └── appsettings.json ├── 10-sample-flat-setup ├── Program.cs ├── SampleFlatSetup.csproj └── config.json ├── 10b-sample-hierarchy ├── Program.cs ├── SampleHierarchy.csproj └── config.json ├── 10c-sample-sections ├── Program.cs ├── SampleSections.csproj └── config.json ├── 10d-sample-section-binding ├── Program.cs ├── SampleSectionBinding.csproj └── config.json ├── 11-asp ├── Asp.csproj ├── FileOptions.cs ├── MarkdownConverter.cs ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Index.cshtml │ ├── Index.cshtml.cs │ ├── InjectConfig.cshtml │ ├── InjectConfig.cshtml.cs │ ├── InjectedIOptions.cshtml │ ├── InjectedIOptions.cshtml.cs │ ├── InjectedIOptionsMonitor.cshtml │ ├── InjectedIOptionsMonitor.cshtml.cs │ ├── InjectedIOptionsSnapshot.cshtml │ ├── InjectedIOptionsSnapshot.cshtml.cs │ ├── InjectedService.cshtml │ ├── InjectedService.cshtml.cs │ ├── Privacy.cshtml │ ├── Privacy.cshtml.cs │ ├── Providers.cshtml │ ├── Providers.cshtml.cs │ ├── Shared │ │ ├── _Layout.cshtml │ │ ├── _Layout.cshtml.css │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── Program.cs ├── Properties │ └── launchSettings.json ├── Services │ └── ExportServices.cs ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── 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 │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── 12-asp-named ├── AspNamed.csproj ├── FileOptions.cs ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Index.cshtml │ ├── Index.cshtml.cs │ ├── InjectConfig.cshtml │ ├── InjectConfig.cshtml.cs │ ├── InjectConfigInRazor.cshtml │ ├── InjectConfigInRazor.cshtml.cs │ ├── InjectedIOptions.cshtml │ ├── InjectedIOptions.cshtml.cs │ ├── InjectedIOptionsMonitor.cshtml │ ├── InjectedIOptionsMonitor.cshtml.cs │ ├── InjectedIOptionsSnapshot.cshtml │ ├── InjectedIOptionsSnapshot.cshtml.cs │ ├── Privacy.cshtml │ ├── Privacy.cshtml.cs │ ├── Providers.cshtml │ ├── Providers.cshtml.cs │ ├── Shared │ │ ├── _Layout.cshtml │ │ ├── _Layout.cshtml.css │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── 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 │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── 13-app-config-asp ├── Controllers │ └── HomeController.cs ├── Models │ └── ErrorViewModel.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── SamplAppConfigAsp.csproj ├── Settings.cs ├── Views │ ├── Home │ │ ├── Index.cshtml │ │ └── Privacy.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ ├── _Layout.cshtml.css │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json ├── setup.sh └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── 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 │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── 14-validation ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Index.cshtml │ ├── Index.cshtml.cs │ ├── Privacy.cshtml │ ├── Privacy.cshtml.cs │ ├── Shared │ │ ├── _Layout.cshtml │ │ ├── _Layout.cshtml.css │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── Program.cs ├── Properties │ └── launchSettings.json ├── ValidateWebHookSettingsOptions.cs ├── Validation.csproj ├── WebHookSettings.cs ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── 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 │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── 15-postconfig-validation ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Index.cshtml │ ├── Index.cshtml.cs │ ├── Privacy.cshtml │ ├── Privacy.cshtml.cs │ ├── Shared │ │ ├── _Layout.cshtml │ │ ├── _Layout.cshtml.css │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── PostValidation.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── WebHookSettings.cs ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── 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 │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── 16-aspire ├── 16-aspire.ApiService │ ├── 16-aspire.ApiService.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── 16-aspire.AppHost │ ├── 16-aspire.AppHost.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── 16-aspire.ServiceDefaults │ ├── 16-aspire.ServiceDefaults.csproj │ └── Extensions.cs ├── 16-aspire.Web │ ├── 16-aspire.Web.csproj │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Counter.razor │ │ │ ├── Error.razor │ │ │ ├── Home.razor │ │ │ └── Weather.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── WeatherApiClient.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── app.css │ │ ├── favicon.png │ │ └── 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 └── 16-aspire.sln ├── dotnet-configuration-in-depth.sln ├── readme.md └── slides ├── Slides.md ├── img ├── background.jpg ├── coding.png ├── compile-time.png ├── configuration-providers.png ├── configuration-source.png ├── dotnet-logo.png ├── gears.png ├── owl.png ├── portrait.jpg ├── portrait.png ├── run-time.png └── session-feedback.png └── themes └── custom-default.css /.devcontainer/dotnet/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/dotnet 3 | { 4 | "name": "C# (.NET)", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/dotnet:1-9.0-bookworm", 7 | // Features to add to the dev container. More info: https://containers.dev/features. 8 | "features": { 9 | "ghcr.io/devcontainers/features/azure-cli:1": {}, 10 | "ghcr.io/devcontainers/features/docker-in-docker:2": {}, 11 | "ghcr.io/devcontainers/features/powershell:1": {} 12 | }, 13 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 14 | "forwardPorts": [5000, 5001], 15 | "portsAttributes": { 16 | "5001": { 17 | "protocol": "https" 18 | } 19 | }, 20 | // Use 'postCreateCommand' to run commands after the container is created. 21 | // "postCreateCommand": "dotnet restore", 22 | "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && dotnet dev-certs https --trust", 23 | "onCreateCommand": "dotnet new install Aspire.ProjectTemplates::9.1.0 --force", 24 | // Configure tool-specific properties. 25 | "customizations": { 26 | // Configure properties specific to VS Code. 27 | "vscode": { 28 | // Add the IDs of extensions you want installed when the container is created. 29 | "extensions": [ 30 | "ms-dotnettools.csdevkit", 31 | "ms-dotnettools.csharp", 32 | "ms-vscode.azurecli", 33 | "ms-azuretools.vscode-bicep", 34 | "ms-azuretools.vscode-azureterraform" 35 | ] 36 | } 37 | } 38 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 39 | // "remoteUser": "root" 40 | } -------------------------------------------------------------------------------- /.devcontainer/slides/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu 3 | { 4 | "name": "Slides", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/base:bullseye", 7 | "features": { 8 | }, 9 | // Features to add to the dev container. More info: https://containers.dev/features. 10 | // "features": {}, 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [], 13 | // Use 'postCreateCommand' to run commands after the container is created. 14 | // "postCreateCommand": "uname -a", 15 | "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", 16 | // Configure tool-specific properties. 17 | "customizations": { 18 | "vscode": { 19 | "settings": { 20 | "markdown.marp.html": "all", 21 | "markdown.marp.themes": [ 22 | "./slides/themes/custom-default.css" 23 | ] 24 | }, 25 | "extensions": [ 26 | "streetsidesoftware.code-spell-checker", 27 | "yzhang.markdown-all-in-one", 28 | "marp-team.marp-vscode", 29 | "bierner.markdown-mermaid", 30 | "hediet.vscode-drawio" 31 | ] 32 | } 33 | } 34 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 35 | // "remoteUser": "root" 36 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.{cmd,[cC][mM][dD]} text eol=crlf 3 | *.{bat,[bB][aA][tT]} text eol=crlf -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "nuget" 14 | directory: "/" 15 | schedule: 16 | interval: "weekly" 17 | -------------------------------------------------------------------------------- /.github/workflows/dotnetversionsweeper.yml: -------------------------------------------------------------------------------- 1 | # The name used in the GitHub UI for the workflow 2 | name: '.net version sweeper' 3 | 4 | # When to run this action: 5 | # - Scheduled on the first of every month 6 | # - Manually runable from the GitHub UI with a reason 7 | on: 8 | schedule: 9 | - cron: '0 0 1 * *' 10 | workflow_dispatch: 11 | inputs: 12 | reason: 13 | description: 'The reason for running the workflow' 14 | required: true 15 | default: 'Manual run' 16 | 17 | # Run on the latest version of Ubuntu 18 | jobs: 19 | version-sweep: 20 | runs-on: ubuntu-latest 21 | 22 | # Checkout the repo into the workspace within the VM 23 | steps: 24 | - uses: actions/checkout@v4 25 | 26 | # If triggered manually, print the reason why 27 | - name: 'Print manual run reason' 28 | if: ${{ github.event_name == 'workflow_dispatch' }} 29 | run: | 30 | echo "Reason: ${{ github.event.inputs.reason }}" 31 | 32 | # Run the .NET version sweeper 33 | # Issues will be automatically created for any non-ignored projects that are targeting non-LTS versions 34 | - name: .NET version sweeper 35 | id: dotnet-version-sweeper 36 | uses: dotnet/versionsweeper@v4.0 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | with: 40 | owner: ${{ github.repository_owner }} 41 | name: ${{ github.repository }} 42 | branch: ${{ github.ref }} 43 | sdkCompliance: true 44 | -------------------------------------------------------------------------------- /.github/workflows/marp-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy marp site to Pages 2 | 3 | on: 4 | # Runs on pushes targeting the default branch 5 | push: 6 | branches: ["main"] 7 | 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 18 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 19 | concurrency: 20 | group: "pages" 21 | cancel-in-progress: false 22 | 23 | jobs: 24 | # Build job 25 | build: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: Copy images 30 | run: mkdir build && cp -R slides/img build/img && cp -R slides/themes build/themes 31 | 32 | - name: Marp Build (README) 33 | uses: docker://marpteam/marp-cli:latest 34 | with: 35 | args: --theme-set slides/themes -o build/index.html --html -- slides/Slides.md 36 | env: 37 | MARP_USER: root:root 38 | - name: Setup Pages 39 | uses: actions/configure-pages@v5 40 | - name: Upload artifact 41 | uses: actions/upload-pages-artifact@v3 42 | with: 43 | # Upload entire repository 44 | path: 'build' 45 | - name: Deploy to GitHub Pages 46 | id: deployment 47 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD024": false, 4 | "MD025": false, 5 | "MD033": false 6 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "HSTS" 4 | ], 5 | "dotnet.defaultSolution": "net-framework-example/NetFrameworkSample.sln" 6 | } -------------------------------------------------------------------------------- /00-basic-console-template/BasicConsoleSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /00-basic-console-template/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /01-console-configuration-json/ConsoleConfigurationJson.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | PreserveNewest 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /01-console-configuration-json/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .Build(); 6 | 7 | var name = "World"; 8 | // See https://aka.ms/new-console-template for more information 9 | Console.WriteLine($"{configuration["greeting"]}, {name}!"); 10 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 11 | -------------------------------------------------------------------------------- /01-console-configuration-json/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hello", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /02-console-configuration-environment/ConsoleConfigurationEnv.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /02-console-configuration-environment/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .Build(); 7 | 8 | var name = "World"; 9 | 10 | // powershell 11 | // $env:environment="qa" 12 | // dotnet run 13 | 14 | // bash 15 | // environment=qa dotnet run 16 | 17 | // See https://aka.ms/new-console-template for more information 18 | Console.WriteLine($"{configuration["greeting"]}, {name}."); 19 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 20 | -------------------------------------------------------------------------------- /02-console-configuration-environment/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hi There", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /03-console-configuration-cmdline/ConsoleConfigurationCmd.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /03-console-configuration-cmdline/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddCommandLine(args) 7 | .Build(); 8 | 9 | // bash 10 | // dotnet run --environment=prod 11 | // environment=qa dotnet run 12 | // environment=qa dotnet run --environment=prod 13 | // greeting=hey dotnet run --environment=prod 14 | 15 | var name = "World"; 16 | // See https://aka.ms/new-console-template for more information 17 | Console.WriteLine($"{configuration["greeting"]}, {name}."); 18 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 19 | 20 | -------------------------------------------------------------------------------- /03-console-configuration-cmdline/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hi There", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /04-console-configuration-user-secrets/ConsoleConfigurationUserSecrets.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | cb8a1ac0-6552-4621-96d0-76b3e69ae17a 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /04-console-configuration-user-secrets/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddUserSecrets() 7 | .AddCommandLine(args) 8 | .Build(); 9 | 10 | var name = "World"; 11 | // See https://aka.ms/new-console-template for more information 12 | Console.WriteLine($"{configuration["greeting"]}, {name}."); 13 | Console.WriteLine($"Environment: {configuration["environment"]}"); 14 | -------------------------------------------------------------------------------- /04-console-configuration-user-secrets/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hi There", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /05-console-configuration-in-memory/ConsoleConfigurationInMem.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | PreserveNewest 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /05-console-configuration-in-memory/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | var configuration = new ConfigurationBuilder() 4 | .AddInMemoryCollection(new Dictionary() 5 | { 6 | ["greeting"] = "Hello", 7 | ["environment"] = "dev" 8 | }) 9 | .Build(); 10 | 11 | Console.WriteLine(configuration["SomeKey"]); 12 | var name = "Chris"; 13 | // Outputs: 14 | // SomeValue 15 | // See https://aka.ms/new-console-template for more information 16 | Console.WriteLine($"{configuration["greeting"]}, {name}!"); 17 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 18 | -------------------------------------------------------------------------------- /05-console-configuration-in-memory/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hello", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /06-console-config-sections/ConsoleConfigSections.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 9a522054-827b-4a65-8321-cb500f49dd28 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /06-console-config-sections/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Spectre.Console; 3 | 4 | IConfigurationRoot configuration = new ConfigurationBuilder() 5 | .AddJsonFile("config.json") 6 | .AddEnvironmentVariables() 7 | .AddUserSecrets(optional: true) 8 | .AddCommandLine(args) 9 | .Build(); 10 | 11 | var name = "World"; 12 | 13 | //dotnet run --greeting:color="blue" 14 | 15 | AnsiConsole.MarkupLine($"[{configuration["greeting:color"]}]{configuration["greeting:message"]}, {name}![/]"); 16 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 17 | -------------------------------------------------------------------------------- /06-console-config-sections/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": { 3 | "message": "Hello", 4 | "color": "red" 5 | }, 6 | "environment": "dev" 7 | } -------------------------------------------------------------------------------- /06b-console-config-sections-cmdline-mappings/ConsoleConfigSectionMappings.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /06b-console-config-sections-cmdline-mappings/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Spectre.Console; 3 | 4 | var mappings = new Dictionary 5 | { 6 | { "--greeting", "greeting:message" }, 7 | { "--color", "greeting:color" }, 8 | { "--env", "environment" }, 9 | }; 10 | IConfigurationRoot configuration = new ConfigurationBuilder() 11 | .AddJsonFile("config.json") 12 | .AddEnvironmentVariables() 13 | .AddUserSecrets(optional: true) 14 | .AddCommandLine(args, mappings) 15 | .Build(); 16 | 17 | //dotnet run --greeting:color="blue" 18 | //dotnet run --color="blue" 19 | 20 | var name = "World"; 21 | // See https://aka.ms/new-console-template for more information 22 | AnsiConsole.MarkupLine($"[{configuration["greeting:color"]}]{configuration["greeting:message"]}, {name}![/]"); 23 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 24 | 25 | -------------------------------------------------------------------------------- /06b-console-config-sections-cmdline-mappings/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": { 3 | "message": "Hello", 4 | "color": "red" 5 | }, 6 | "environment": "dev" 7 | } -------------------------------------------------------------------------------- /07-console-key-per-file/ConsoleConfigurationKeys.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | 782d4486-cc36-408d-8b17-d299f7e6a085 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /07-console-key-per-file/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | var path = Path.Combine( 4 | Directory.GetCurrentDirectory(), "./keyPerFile"); 5 | 6 | IConfigurationRoot configuration = new ConfigurationBuilder() 7 | .AddJsonFile("config.json") 8 | .AddKeyPerFile(directoryPath: path, optional: true) 9 | .AddUserSecrets(optional:true) 10 | .Build(); 11 | 12 | var name = "World"; 13 | // See https://aka.ms/new-console-template for more information 14 | 15 | 16 | //$Env:ENVIRONMENT="qa"; dotnet run 17 | //$Env:ENVIRONMENT="production"; dotnet run 18 | //$Env:ENVIRONMENT=$NULL 19 | 20 | Console.WriteLine($"{configuration["greeting"]}, {name}."); 21 | Console.WriteLine($"Configuration: {configuration["environment"]}"); 22 | 23 | var debugView = configuration.GetDebugView(); 24 | Console.WriteLine(debugView.ToString()); -------------------------------------------------------------------------------- /07-console-key-per-file/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Hi There", 3 | "environment": "dev" 4 | } -------------------------------------------------------------------------------- /07-console-key-per-file/keyPerFile/Logging__KeyFile: -------------------------------------------------------------------------------- 1 | file value -------------------------------------------------------------------------------- /07-console-key-per-file/keyPerFile/SecretKey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/07-console-key-per-file/keyPerFile/SecretKey -------------------------------------------------------------------------------- /07-console-key-per-file/keyPerFile/environment: -------------------------------------------------------------------------------- 1 | QA -------------------------------------------------------------------------------- /07-console-key-per-file/keyPerFile/greeting: -------------------------------------------------------------------------------- 1 | Hi ONETUG! -------------------------------------------------------------------------------- /08-console-keyvault/ConsoleKeyvault.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 2d3ed947-36c1-4d6f-afaf-48e661f4d837 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /08-console-keyvault/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.AspNetCore.Builder; 3 | using Azure.Identity; 4 | using Azure.Security.KeyVault; 5 | using Azure.Security.KeyVault.Secrets; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | var keyVaultName = builder.Configuration["KeyVaultName"] ?? throw new ArgumentNullException("KeyVaultName"); 9 | var keyVaultUri = $"https://{keyVaultName}.vault.azure.net/"; 10 | 11 | //Connect to your KeyVault using the URI 12 | builder.Configuration 13 | .AddAzureKeyVault(new Uri(keyVaultUri), new DefaultAzureCredential()); 14 | var app = builder.Build(); 15 | var configuration = app.Configuration; 16 | 17 | Console.WriteLine($"Message: {configuration["Message"]}"); 18 | 19 | var name = args.Any() ? args[0] : "World"; 20 | // See https://aka.ms/new-console-template for more information 21 | Console.WriteLine($"{configuration["greeting"]}, {name}."); 22 | Console.WriteLine($"Environment: {configuration["environment"]}"); 23 | -------------------------------------------------------------------------------- /08-console-keyvault/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /08-console-keyvault/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "greeting": "Hi There", 10 | "environment": "dev", 11 | "KeyVaultName": "cayersdotnetkv" 12 | } 13 | -------------------------------------------------------------------------------- /08-console-keyvault/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | location=eastus 4 | rg=rg-dotnet 5 | kvName=cayersdotnetkv 6 | 7 | az group create --name ${rg} --location ${location} 8 | 9 | az keyvault create --location ${location} --name ${kvName} --resource-group ${rg} 10 | 11 | 12 | # Assign the Key Vault Contributor role to the current user 13 | userId=$(az ad signed-in-user show --query id --output tsv) 14 | az role assignment create --assignee ${userId} --role "Key Vault Administrator" --scope /subscriptions/$(az account show --query id --output tsv)/resourceGroups/${rg}/providers/Microsoft.KeyVault/vaults/${kvName} 15 | 16 | az keyvault secret set --name Message --vault-name ${kvName} --value "Hello from KV" 17 | -------------------------------------------------------------------------------- /09-hosted-console-template/HostedConsoleTemplate.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /09-hosted-console-template/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | 3 | using IHost host = Host.CreateApplicationBuilder(args).Build(); 4 | 5 | // Application code should start here. 6 | Console.WriteLine("Hello, World!"); 7 | await host.RunAsync(); 8 | -------------------------------------------------------------------------------- /09-hosted-console-template/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyOne": 1, 3 | "KeyTwo": true, 4 | "KeyThree": { 5 | "Message": "Thanks for checking this out!" 6 | } 7 | } -------------------------------------------------------------------------------- /09b-alternate-hosted-template/AltHostedConsoleTemplate.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /09b-alternate-hosted-template/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | using IHost host = Host.CreateApplicationBuilder(args).Build(); 6 | 7 | // Ask the service provider for the configuration abstraction. 8 | IConfiguration config = host.Services.GetRequiredService(); 9 | 10 | // Get values from the config given their key and their target type. 11 | int keyOneValue = config.GetValue("KeyOne"); 12 | bool keyTwoValue = config.GetValue("KeyTwo"); 13 | string? keyThreeNestedValue = config.GetValue("KeyThree:Message"); 14 | 15 | // Write the values to the console. 16 | Console.WriteLine($"KeyOne = {keyOneValue}"); 17 | Console.WriteLine($"KeyTwo = {keyTwoValue}"); 18 | Console.WriteLine($"KeyThree:Message = {keyThreeNestedValue}"); 19 | 20 | // Application code which might rely on the config could start here. 21 | 22 | await host.RunAsync(); 23 | 24 | // This will output the following: 25 | // KeyOne = 1 26 | // KeyTwo = True 27 | // KeyThree:Message = Thanks for checking this out! -------------------------------------------------------------------------------- /09b-alternate-hosted-template/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyOne": 1, 3 | "KeyTwo": true, 4 | "KeyThree": { 5 | "Message": "Thanks for checking this out!" 6 | } 7 | } -------------------------------------------------------------------------------- /09c-indexer-api/IndexerApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /09c-indexer-api/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | using IHost host = Host.CreateApplicationBuilder(args).Build(); 6 | 7 | // Ask the service provider for the configuration abstraction. 8 | IConfiguration config = host.Services.GetRequiredService(); 9 | 10 | // Get values from the config given their key and their target type. 11 | string? ipOne = config["IPAddressRange:0"]; 12 | string? ipTwo = config["IPAddressRange:1"]; 13 | string? ipThree = config["IPAddressRange:2"]; 14 | string? versionOne = config["SupportedVersions:v1"]; 15 | string? versionThree = config["SupportedVersions:v3"]; 16 | 17 | // Write the values to the console. 18 | Console.WriteLine($"IPAddressRange:0 = {ipOne}"); 19 | Console.WriteLine($"IPAddressRange:1 = {ipTwo}"); 20 | Console.WriteLine($"IPAddressRange:2 = {ipThree}"); 21 | Console.WriteLine($"SupportedVersions:v1 = {versionOne}"); 22 | Console.WriteLine($"SupportedVersions:v3 = {versionThree}"); 23 | 24 | // Application code which might rely on the config could start here. 25 | 26 | await host.RunAsync(); 27 | 28 | // This will output the following: 29 | // IPAddressRange:0 = 46.36.198.123 30 | // IPAddressRange:1 = 46.36.198.124 31 | // IPAddressRange:2 = 46.36.198.125 32 | // SupportedVersions:v1 = 1.0.0 33 | // SupportedVersions:v3 = 3.0.7 -------------------------------------------------------------------------------- /09c-indexer-api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "SupportedVersions": { 3 | "v1": "1.0.0", 4 | "v3": "3.0.7" 5 | }, 6 | "IPAddressRange": [ 7 | "46.36.198.123", 8 | "46.36.198.124", 9 | "46.36.198.125" 10 | ] 11 | } -------------------------------------------------------------------------------- /10-sample-flat-setup/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddUserSecrets(optional: true) 7 | .AddCommandLine(args) 8 | .Build(); 9 | 10 | Console.WriteLine($"markdownStyle: {configuration["markdownStyle"]}"); 11 | Console.WriteLine($"pdfOutputDir: {configuration["pdfOutputDir"]}"); 12 | Console.WriteLine($"pdfTemplateFile: {configuration["pdfTemplateFile"]}"); 13 | Console.WriteLine($"docOutputDir: {configuration["docOutputDir"]}"); 14 | Console.WriteLine($"docTemplateFile: {configuration["docTemplateFile"]}"); 15 | Console.WriteLine($"htmlOutputDir: {configuration["htmlOutputDir"]}"); 16 | Console.WriteLine($"htmlTemplateFile: {configuration["htmlTemplateFile"]}"); 17 | -------------------------------------------------------------------------------- /10-sample-flat-setup/SampleFlatSetup.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | cb8a1ac0-6552-4621-96d0-76b3e69ae17a 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /10-sample-flat-setup/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownStyle": "github", 3 | "pdfOutputDir": "./output/pdf/", 4 | "pdfTemplateFile": "./templates/template.pdf", 5 | "docOutputDir": "./output/doc/", 6 | "docTemplateFile": "./templates/template.doc", 7 | "htmlOutputDir": "./output/html/", 8 | "htmlTemplateFile": "./templates/template.html" 9 | } -------------------------------------------------------------------------------- /10b-sample-hierarchy/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddUserSecrets(optional: true) 7 | .AddCommandLine(args) 8 | .Build(); 9 | 10 | 11 | Console.WriteLine($"markdownStyle: {configuration["markdownStyle"]}"); 12 | Console.WriteLine($"pdf FileExtension: {configuration["pdf:FileExtension"]}"); 13 | Console.WriteLine($"pdf OutputDir: {configuration["pdf:OutputDir"]}"); 14 | Console.WriteLine($"pdf TemplateFile: {configuration["pdf:TemplateFile"]}"); 15 | Console.WriteLine($"doc FileExtension: {configuration["doc:FileExtension"]}"); 16 | Console.WriteLine($"doc OutputDir: {configuration["doc:OutputDir"]}"); 17 | Console.WriteLine($"doc TemplateFile: {configuration["doc:TemplateFile"]}"); 18 | Console.WriteLine($"html FileExtension: {configuration["html:FileExtension"]}"); 19 | Console.WriteLine($"html OutputDir: {configuration["html:OutputDir"]}"); 20 | Console.WriteLine($"html TemplateFile: {configuration["html:TemplateFile"]}"); 21 | -------------------------------------------------------------------------------- /10b-sample-hierarchy/SampleHierarchy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | cb8a1ac0-6552-4621-96d0-76b3e69ae17a 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /10b-sample-hierarchy/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownStyle": "github", 3 | "pdf":{ 4 | "fileExtension": "pdf", 5 | "outputDir": "./output/pdf/", 6 | "templateFile": "./templates/template.pdf" 7 | }, 8 | "doc":{ 9 | "fileExtension": "doc", 10 | "outputDir": "./output/doc/", 11 | "templateFile": "./templates/template.doc" 12 | }, 13 | "html":{ 14 | "fileExtension": "html", 15 | "outputDir": "./output/html/", 16 | "templateFile": "./templates/template.html" 17 | } 18 | } -------------------------------------------------------------------------------- /10c-sample-sections/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddUserSecrets(optional: true) 7 | .AddCommandLine(args) 8 | .Build(); 9 | 10 | 11 | Console.WriteLine($"markdownStyle: {configuration["markdownStyle"]}"); 12 | 13 | var options = configuration.GetSection("pdf"); 14 | WriteOptions(options); 15 | options = configuration.GetSection("doc"); 16 | WriteOptions(options); 17 | options = configuration.GetSection("html"); 18 | WriteOptions(options); 19 | 20 | 21 | void WriteOptions(IConfiguration config) 22 | { 23 | var fileExtension = config["fileExtension"]; 24 | Console.WriteLine($"{fileExtension} fileExtension: {fileExtension}"); 25 | Console.WriteLine($"{fileExtension} OutputDir: {config["OutputDir"]}"); 26 | Console.WriteLine($"{fileExtension} TemplateFile: {config["TemplateFile"]}"); 27 | } -------------------------------------------------------------------------------- /10c-sample-sections/SampleSections.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | cb8a1ac0-6552-4621-96d0-76b3e69ae17a 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /10c-sample-sections/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownStyle": "github", 3 | "pdf":{ 4 | "fileExtension": "pdf", 5 | "outputDir": "./output/pdf/", 6 | "templateFile": "./templates/template.pdf" 7 | }, 8 | "doc":{ 9 | "fileExtension": "doc", 10 | "outputDir": "./output/doc/", 11 | "templateFile": "./templates/template.doc" 12 | }, 13 | "html":{ 14 | "fileExtension": "html", 15 | "outputDir": "./output/html/", 16 | "templateFile": "./templates/template.html" 17 | } 18 | } -------------------------------------------------------------------------------- /10d-sample-section-binding/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | IConfigurationRoot configuration = new ConfigurationBuilder() 4 | .AddJsonFile("config.json") 5 | .AddEnvironmentVariables() 6 | .AddUserSecrets(optional: true) 7 | .AddCommandLine(args) 8 | .Build(); 9 | 10 | 11 | Console.WriteLine($"markdownStyle: {configuration["markdownStyle"]}"); 12 | 13 | var pdfOptions = new FileOptions(); 14 | configuration.GetSection("pdf") 15 | .Bind(pdfOptions); 16 | WriteOptions(pdfOptions); 17 | 18 | var docOptions = configuration.GetSection("doc") 19 | .Get(); 20 | WriteOptions(docOptions); 21 | 22 | var htmlOptions = configuration.GetSection("html") 23 | .Get(); 24 | WriteOptions(htmlOptions); 25 | 26 | 27 | void WriteOptions(FileOptions? options) 28 | { 29 | Console.WriteLine($"{options?.FileExtension} fileExtension: {options?.FileExtension}"); 30 | Console.WriteLine($"{options?.FileExtension} OutputDir: {options?.OutputDir}"); 31 | Console.WriteLine($"{options?.FileExtension} TemplateFile: {options?.TemplateFile}"); 32 | } 33 | 34 | 35 | public class FileOptions 36 | { 37 | public string FileExtension { get; set; } =""; 38 | public string OutputDir { get; set; } =""; 39 | public string TemplateFile { get; set; } =""; 40 | } -------------------------------------------------------------------------------- /10d-sample-section-binding/SampleSectionBinding.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | SampleApp 7 | enable 8 | enable 9 | cb8a1ac0-6552-4621-96d0-76b3e69ae17a 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /10d-sample-section-binding/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownStyle": "github", 3 | "pdf":{ 4 | "FileExtension": "pdf", 5 | "OutputDir": "./output/pdf/", 6 | "TemplateFile": "./templates/template.pdf" 7 | }, 8 | "doc":{ 9 | "FileExtension": "doc", 10 | "OutputDir": "./output/doc/", 11 | "TemplateFile": "./templates/template.doc" 12 | }, 13 | "html":{ 14 | "FileExtension": "html", 15 | "OutputDir": "./output/html/", 16 | "TemplateFile": "./templates/template.html" 17 | } 18 | } -------------------------------------------------------------------------------- /11-asp/Asp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | SampleAsp 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /11-asp/FileOptions.cs: -------------------------------------------------------------------------------- 1 | 2 | public class FileOptions 3 | { 4 | public bool Enabled { get; set; } 5 | public string FileExtension { get; set; } = ""; 6 | public string OutputDir { get; set; } = ""; 7 | public string TemplateFile { get; set; } = ""; 8 | } -------------------------------------------------------------------------------- /11-asp/MarkdownConverter.cs: -------------------------------------------------------------------------------- 1 | public class MarkdownConverter 2 | { 3 | public string MarkdownStyle { get; set; } = string.Empty; 4 | public FileOptions Pdf { get; set; } = new FileOptions(); 5 | public FileOptions Doc { get; set; } = new FileOptions(); 6 | public FileOptions Html { get; set; } = new FileOptions(); 7 | } 8 | -------------------------------------------------------------------------------- /11-asp/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /11-asp/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 8 | [IgnoreAntiforgeryToken] 9 | public class ErrorModel : PageModel 10 | { 11 | public string? RequestId { get; set; } 12 | 13 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 14 | 15 | private readonly ILogger _logger; 16 | 17 | public ErrorModel(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public void OnGet() 23 | { 24 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /11-asp/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | 12 | -------------------------------------------------------------------------------- /11-asp/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class IndexModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | public IndexModel(ILogger logger) 10 | { 11 | _logger = logger; 12 | } 13 | 14 | public void OnGet() 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /11-asp/Pages/InjectConfig.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectConfigModel 3 | @{ 4 | ViewData["Title"] = "InjectConfiguration"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | 12 | @foreach(var option in Model.Options) { 13 |

@option.FileExtension

14 |
    15 |
  • @option.Enabled
  • 16 |
  • @option.FileExtension
  • 17 |
  • @option.OutputDir
  • 18 |
  • @option.TemplateFile
  • 19 |
20 | } -------------------------------------------------------------------------------- /11-asp/Pages/InjectConfig.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class InjectConfigModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | public List Options {get;private set;} = new List(); 10 | public InjectConfigModel(ILogger logger, IConfiguration configuration) 11 | { 12 | _logger = logger; 13 | var pdf = configuration.GetSection("MarkdownConverter:pdf").Get(); 14 | var doc = configuration.GetSection("MarkdownConverter:doc").Get(); 15 | var html = configuration.GetSection("MarkdownConverter:html").Get(); 16 | if(pdf is not null) 17 | { 18 | Options.Add(pdf); 19 | } 20 | if(doc is not null) 21 | { 22 | Options.Add(doc); 23 | } 24 | if(html is not null) 25 | { 26 | Options.Add(html); 27 | } 28 | } 29 | 30 | public void OnGet() 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptions.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptions"; 5 | } 6 | 7 |
8 |

Injected IOptions<T>

9 |
10 | 11 |

Markdown Settings

12 |

MarkdownStyle: @Model.MarkdownConverterSettings.MarkdownStyle

13 |

Pdf

14 |
    15 |
  • @Model.MarkdownConverterSettings.Pdf.Enabled
  • 16 |
  • @Model.MarkdownConverterSettings.Pdf.FileExtension
  • 17 |
  • @Model.MarkdownConverterSettings.Pdf.OutputDir
  • 18 |
  • @Model.MarkdownConverterSettings.Pdf.TemplateFile
  • 19 |
20 | 21 |

Doc

22 |
    23 |
  • @Model.MarkdownConverterSettings.Doc.Enabled
  • 24 |
  • @Model.MarkdownConverterSettings.Doc.FileExtension
  • 25 |
  • @Model.MarkdownConverterSettings.Doc.OutputDir
  • 26 |
  • @Model.MarkdownConverterSettings.Doc.TemplateFile
  • 27 |
28 | 29 |

Html

30 |
    31 |
  • @Model.MarkdownConverterSettings.Html.Enabled
  • 32 |
  • @Model.MarkdownConverterSettings.Html.FileExtension
  • 33 |
  • @Model.MarkdownConverterSettings.Html.OutputDir
  • 34 |
  • @Model.MarkdownConverterSettings.Html.TemplateFile
  • 35 |
-------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptions.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public MarkdownConverter MarkdownConverterSettings; 11 | 12 | public InjectedIOptionsModel(ILogger logger, IOptions markdown) 13 | { 14 | _logger = logger; 15 | MarkdownConverterSettings = markdown.Value; 16 | } 17 | 18 | public void OnGet() 19 | { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptionsMonitor.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsMonitorModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptionsMonitor"; 5 | } 6 | 7 |
8 |

Injected IOptionsMonitor<T>

9 |
10 | 11 |

Markdown Settings

12 |

MarkdownStyle: @Model.MarkdownConverterSettings.MarkdownStyle

13 |

Pdf

14 |
    15 |
  • @Model.MarkdownConverterSettings.Pdf.Enabled
  • 16 |
  • @Model.MarkdownConverterSettings.Pdf.FileExtension
  • 17 |
  • @Model.MarkdownConverterSettings.Pdf.OutputDir
  • 18 |
  • @Model.MarkdownConverterSettings.Pdf.TemplateFile
  • 19 |
20 | 21 |

Doc

22 |
    23 |
  • @Model.MarkdownConverterSettings.Doc.Enabled
  • 24 |
  • @Model.MarkdownConverterSettings.Doc.FileExtension
  • 25 |
  • @Model.MarkdownConverterSettings.Doc.OutputDir
  • 26 |
  • @Model.MarkdownConverterSettings.Doc.TemplateFile
  • 27 |
28 | 29 |

Html

30 |
    31 |
  • @Model.MarkdownConverterSettings.Html.Enabled
  • 32 |
  • @Model.MarkdownConverterSettings.Html.FileExtension
  • 33 |
  • @Model.MarkdownConverterSettings.Html.OutputDir
  • 34 |
  • @Model.MarkdownConverterSettings.Html.TemplateFile
  • 35 |
-------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptionsMonitor.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsMonitorModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public MarkdownConverter MarkdownConverterSettings; 11 | 12 | public InjectedIOptionsMonitorModel(ILogger logger, IOptionsMonitor markdown) 13 | { 14 | _logger = logger; 15 | MarkdownConverterSettings = markdown.CurrentValue; 16 | 17 | } 18 | 19 | public void OnGet() 20 | { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptionsSnapshot.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsSnapshotModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptionsSnapshot"; 5 | } 6 | 7 |
8 |

Injected IOptionsSnapshot<T>

9 |
10 | 11 |

Markdown Settings

12 |

MarkdownStyle: @Model.MarkdownConverterSettings.MarkdownStyle

13 |

Pdf

14 |
    15 |
  • @Model.MarkdownConverterSettings.Pdf.Enabled
  • 16 |
  • @Model.MarkdownConverterSettings.Pdf.FileExtension
  • 17 |
  • @Model.MarkdownConverterSettings.Pdf.OutputDir
  • 18 |
  • @Model.MarkdownConverterSettings.Pdf.TemplateFile
  • 19 |
20 | 21 |

Doc

22 |
    23 |
  • @Model.MarkdownConverterSettings.Doc.Enabled
  • 24 |
  • @Model.MarkdownConverterSettings.Doc.FileExtension
  • 25 |
  • @Model.MarkdownConverterSettings.Doc.OutputDir
  • 26 |
  • @Model.MarkdownConverterSettings.Doc.TemplateFile
  • 27 |
28 | 29 |

Html

30 |
    31 |
  • @Model.MarkdownConverterSettings.Html.Enabled
  • 32 |
  • @Model.MarkdownConverterSettings.Html.FileExtension
  • 33 |
  • @Model.MarkdownConverterSettings.Html.OutputDir
  • 34 |
  • @Model.MarkdownConverterSettings.Html.TemplateFile
  • 35 |
-------------------------------------------------------------------------------- /11-asp/Pages/InjectedIOptionsSnapshot.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsSnapshotModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public MarkdownConverter MarkdownConverterSettings; 11 | public InjectedIOptionsSnapshotModel(ILogger logger, IOptionsSnapshot markdown) 12 | { 13 | _logger = logger; 14 | MarkdownConverterSettings = markdown.Value; 15 | } 16 | 17 | public void OnGet() 18 | { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /11-asp/Pages/InjectedService.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedServiceModel 3 | @{ 4 | ViewData["Title"] = "InjectConfiguration"; 5 | } 6 | 7 | 8 |
9 |

Injected Service

10 |
11 | 12 |

Markdown Settings

13 |

MarkdownStyle: @Model.MarkdownConverterSettings.MarkdownStyle

14 |

Pdf

15 |
    16 |
  • @Model.MarkdownConverterSettings.Pdf.Enabled
  • 17 |
  • @Model.MarkdownConverterSettings.Pdf.FileExtension
  • 18 |
  • @Model.MarkdownConverterSettings.Pdf.OutputDir
  • 19 |
  • @Model.MarkdownConverterSettings.Pdf.TemplateFile
  • 20 |
21 | 22 |

Doc

23 |
    24 |
  • @Model.MarkdownConverterSettings.Doc.Enabled
  • 25 |
  • @Model.MarkdownConverterSettings.Doc.FileExtension
  • 26 |
  • @Model.MarkdownConverterSettings.Doc.OutputDir
  • 27 |
  • @Model.MarkdownConverterSettings.Doc.TemplateFile
  • 28 |
29 | 30 |

Html

31 |
    32 |
  • @Model.MarkdownConverterSettings.Html.Enabled
  • 33 |
  • @Model.MarkdownConverterSettings.Html.FileExtension
  • 34 |
  • @Model.MarkdownConverterSettings.Html.OutputDir
  • 35 |
  • @Model.MarkdownConverterSettings.Html.TemplateFile
  • 36 |
-------------------------------------------------------------------------------- /11-asp/Pages/InjectedService.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using SampleAsp.Services; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedServiceModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public MarkdownConverter MarkdownConverterSettings; 11 | 12 | public InjectedServiceModel(ILogger logger, IExportService exportService) 13 | { 14 | _logger = logger; 15 | MarkdownConverterSettings = exportService.GetMarkdownConverter(); 16 | } 17 | 18 | public void OnGet() 19 | { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11-asp/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

9 | -------------------------------------------------------------------------------- /11-asp/Pages/Privacy.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class PrivacyModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public PrivacyModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /11-asp/Pages/Providers.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ProvidersModel 3 | @{ 4 | ViewData["Title"] = "Providers"; 5 | } 6 | 7 |
8 |

Providers

9 |
10 | 11 |
    12 | @foreach(var provider in Model.Providers) { 13 |
  • @provider
  • 14 | } 15 |
-------------------------------------------------------------------------------- /11-asp/Pages/Providers.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class ProvidersModel : PageModel 7 | { 8 | private IConfigurationRoot ConfigRoot; 9 | private readonly ILogger _logger; 10 | public IEnumerable Providers {get; private set;} 11 | public ProvidersModel(ILogger logger, IConfiguration configRoot) 12 | { 13 | _logger = logger; 14 | ConfigRoot = (IConfigurationRoot)configRoot; 15 | Providers = ConfigRoot.Providers.Select(p => p?.ToString()); 16 | } 17 | 18 | public void OnGet() 19 | { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11-asp/Pages/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - SampleAsp 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | 39 |
40 |
41 | © 2022 - SampleAsp - Privacy 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | @await RenderSectionAsync("Scripts", required: false) 50 | 51 | -------------------------------------------------------------------------------- /11-asp/Pages/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /11-asp/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /11-asp/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using SampleAsp 2 | @namespace SampleAsp.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /11-asp/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /11-asp/Program.cs: -------------------------------------------------------------------------------- 1 | using SampleAsp.Services; 2 | 3 | var builder = WebApplication.CreateBuilder(args); 4 | 5 | // Add services to the container. 6 | builder.Services.Configure(builder.Configuration.GetSection("MarkdownConverter")); 7 | 8 | //builder.Services.AddSingleton(); 9 | builder.Services.AddTransient(); 10 | // builder.Services.AddScoped(); 11 | builder.Services.AddRazorPages(); 12 | 13 | var app = builder.Build(); 14 | 15 | // Configure the HTTP request pipeline. 16 | if (!app.Environment.IsDevelopment()) 17 | { 18 | app.UseExceptionHandler("/Error"); 19 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 20 | app.UseHsts(); 21 | } 22 | 23 | app.UseHttpsRedirection(); 24 | app.UseStaticFiles(); 25 | 26 | app.UseRouting(); 27 | 28 | app.UseAuthorization(); 29 | 30 | app.MapRazorPages(); 31 | 32 | app.Run(); 33 | -------------------------------------------------------------------------------- /11-asp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:45522", 7 | "sslPort": 44316 8 | } 9 | }, 10 | "profiles": { 11 | "SampleAsp": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "https://localhost:7229;http://localhost:5275", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /11-asp/Services/ExportServices.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Options; 2 | namespace SampleAsp.Services; 3 | 4 | public interface IExportService 5 | { 6 | MarkdownConverter GetMarkdownConverter(); 7 | } 8 | 9 | public class ExportService : IExportService 10 | { 11 | private readonly MarkdownConverter _markdown; 12 | public ExportService(IOptions markdown) 13 | { 14 | _markdown = markdown.Value; 15 | } 16 | // public ExportService(IOptionsMonitor markdown) 17 | // { 18 | // _markdown = markdown.CurrentValue; 19 | // } 20 | 21 | public MarkdownConverter GetMarkdownConverter() 22 | { 23 | return _markdown; 24 | } 25 | } -------------------------------------------------------------------------------- /11-asp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /11-asp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "MarkdownConverter": { 3 | "markdownStyle": "github", 4 | "pdf": { 5 | "Enabled": true, 6 | "FileExtension": "pdf", 7 | "OutputDir": "./output/pdf/", 8 | "TemplateFile": "./templates/template.pdf" 9 | }, 10 | "doc": { 11 | "Enabled": false, 12 | "FileExtension": "doc", 13 | "OutputDir": "./output/doc/", 14 | "TemplateFile": "./templates/template.doc" 15 | }, 16 | "html": { 17 | "Enabled": false, 18 | "FileExtension": "html", 19 | "OutputDir": "./output/html/", 20 | "TemplateFile": "./templates/template.html" 21 | } 22 | }, 23 | "Logging": { 24 | "LogLevel": { 25 | "Default": "Information", 26 | "Microsoft.AspNetCore": "Warning" 27 | } 28 | }, 29 | "AllowedHosts": "*" 30 | } -------------------------------------------------------------------------------- /11-asp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | html { 7 | font-size: 16px; 8 | } 9 | } 10 | 11 | html { 12 | position: relative; 13 | min-height: 100%; 14 | } 15 | 16 | body { 17 | margin-bottom: 60px; 18 | } -------------------------------------------------------------------------------- /11-asp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/11-asp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /11-asp/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /11-asp/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2021 Twitter, Inc. 4 | Copyright (c) 2011-2021 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /11-asp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::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;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}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[data-bs-original-title],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:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}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:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}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:#6c757d;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]::-webkit-calendar-picker-indicator{display:none}[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]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-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} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /11-asp/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /11-asp/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /11-asp/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /12-asp-named/AspNamed.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | SampleAsp 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /12-asp-named/FileOptions.cs: -------------------------------------------------------------------------------- 1 | 2 | public class FileOptions 3 | { 4 | public string FileExtension { get; set; } =""; 5 | public string OutputDir { get; set; } =""; 6 | public string TemplateFile { get; set; } =""; 7 | } -------------------------------------------------------------------------------- /12-asp-named/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 8 | [IgnoreAntiforgeryToken] 9 | public class ErrorModel : PageModel 10 | { 11 | public string? RequestId { get; set; } 12 | 13 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 14 | 15 | private readonly ILogger _logger; 16 | 17 | public ErrorModel(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public void OnGet() 23 | { 24 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | 12 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class IndexModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | public IndexModel(ILogger logger) 10 | { 11 | _logger = logger; 12 | } 13 | 14 | public void OnGet() 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectConfig.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectConfigModel 3 | @{ 4 | ViewData["Title"] = "InjectConfiguration"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | 12 | @foreach(var option in Model.Options) { 13 |

@option.FileExtension

14 |
    15 |
  • @option.FileExtension
  • 16 |
  • @option.OutputDir
  • 17 |
  • @option.TemplateFile
  • 18 |
19 | } -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectConfig.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class InjectConfigModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | public List Options {get;private set;} = new List(); 10 | public InjectConfigModel(ILogger logger, IConfiguration configuration) 11 | { 12 | _logger = logger; 13 | var pdf = configuration.GetSection("MarkdownConverter:pdf").Get(); 14 | var doc = configuration.GetSection("MarkdownConverter:doc").Get(); 15 | var html = configuration.GetSection("MarkdownConverter:html").Get(); 16 | if(pdf is not null) 17 | { 18 | Options.Add(pdf); 19 | } 20 | if(doc is not null) 21 | { 22 | Options.Add(doc); 23 | } 24 | if(html is not null) 25 | { 26 | Options.Add(html); 27 | } 28 | } 29 | 30 | public void OnGet() 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectConfigInRazor.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectConfigInRazorModel 3 | @using Microsoft.Extensions.Configuration 4 | @inject IConfiguration Configuration 5 | @{ 6 | ViewData["Title"] = "InjectConfiguration"; 7 | var pdf = Configuration.GetSection("MarkdownConverter:pdf").Get(); 8 | var doc = Configuration.GetSection("MarkdownConverter:doc").Get(); 9 | var html = Configuration.GetSection("MarkdownConverter:html").Get(); 10 | } 11 | 12 |
13 |

Welcome

14 |

Learn about building Web apps with ASP.NET Core.

15 |
16 | 17 | 18 |

Pdf

19 |
    20 |
  • @pdf?.FileExtension
  • 21 |
  • @pdf?.OutputDir
  • 22 |
  • @pdf?.TemplateFile
  • 23 |
24 | 25 |

Doc

26 |
    27 |
  • @doc?.FileExtension
  • 28 |
  • @doc?.OutputDir
  • 29 |
  • @doc?.TemplateFile
  • 30 |
31 | 32 | 33 |

Html

34 |
    35 |
  • @html?.FileExtension
  • 36 |
  • @html?.OutputDir
  • 37 |
  • @html?.TemplateFile
  • 38 |
-------------------------------------------------------------------------------- /12-asp-named/Pages/InjectConfigInRazor.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class InjectConfigInRazorModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | public InjectConfigInRazorModel(ILogger logger) 10 | { 11 | _logger = logger; 12 | } 13 | 14 | public void OnGet() 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptions.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptions"; 5 | } 6 | 7 |
8 |

Injected IOptions<T>

9 |
10 | 11 |
    12 |
  • @Model.PdfOptions.FileExtension
  • 13 |
  • @Model.PdfOptions.OutputDir
  • 14 |
  • @Model.PdfOptions.TemplateFile
  • 15 |
-------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptions.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public FileOptions PdfOptions = new FileOptions(); 11 | public FileOptions DocOptions = new FileOptions(); 12 | public FileOptions HtmlOptions = new FileOptions(); 13 | 14 | public InjectedIOptionsModel(ILogger logger, IOptions fileOptions) 15 | { 16 | _logger = logger; 17 | PdfOptions = fileOptions.Value; 18 | // DocOptions = fileOptions.Get("doc"); 19 | // HtmlOptions = fileOptions.Get("html"); 20 | } 21 | 22 | public void OnGet() 23 | { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptionsMonitor.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsMonitorModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptionsMonitor"; 5 | } 6 | 7 |
8 |

Injected IOptionsMonitor<T>

9 |
10 | 11 |

Pdf

12 |
    13 |
  • @Model.PdfOptions.FileExtension
  • 14 |
  • @Model.PdfOptions.OutputDir
  • 15 |
  • @Model.PdfOptions.TemplateFile
  • 16 |
17 | 18 |

Doc

19 |
    20 |
  • @Model.DocOptions.FileExtension
  • 21 |
  • @Model.DocOptions.OutputDir
  • 22 |
  • @Model.DocOptions.TemplateFile
  • 23 |
24 | 25 | 26 |

Html

27 |
    28 |
  • @Model.HtmlOptions.FileExtension
  • 29 |
  • @Model.HtmlOptions.OutputDir
  • 30 |
  • @Model.HtmlOptions.TemplateFile
  • 31 |
-------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptionsMonitor.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsMonitorModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public FileOptions PdfOptions; 11 | public FileOptions DocOptions; 12 | public FileOptions HtmlOptions; 13 | 14 | public InjectedIOptionsMonitorModel(ILogger logger, IOptionsSnapshot fileOptions) 15 | { 16 | _logger = logger; 17 | PdfOptions = fileOptions.Get("pdf"); 18 | DocOptions = fileOptions.Get("doc"); 19 | HtmlOptions = fileOptions.Get("html"); 20 | } 21 | 22 | public void OnGet() 23 | { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptionsSnapshot.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model InjectedIOptionsSnapshotModel 3 | @{ 4 | ViewData["Title"] = "InjectedIOptionsSnapshot"; 5 | } 6 | 7 |
8 |

Injected IOptionsSnapshot<T>

9 |
10 | 11 |

Pdf

12 |
    13 |
  • @Model.PdfOptions.FileExtension
  • 14 |
  • @Model.PdfOptions.OutputDir
  • 15 |
  • @Model.PdfOptions.TemplateFile
  • 16 |
17 | 18 |

Doc

19 |
    20 |
  • @Model.DocOptions.FileExtension
  • 21 |
  • @Model.DocOptions.OutputDir
  • 22 |
  • @Model.DocOptions.TemplateFile
  • 23 |
24 | 25 | 26 |

Html

27 |
    28 |
  • @Model.HtmlOptions.FileExtension
  • 29 |
  • @Model.HtmlOptions.OutputDir
  • 30 |
  • @Model.HtmlOptions.TemplateFile
  • 31 |
-------------------------------------------------------------------------------- /12-asp-named/Pages/InjectedIOptionsSnapshot.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace SampleAsp.Pages; 6 | 7 | public class InjectedIOptionsSnapshotModel : PageModel 8 | { 9 | private readonly ILogger _logger; 10 | public FileOptions PdfOptions; 11 | public FileOptions DocOptions; 12 | public FileOptions HtmlOptions; 13 | public InjectedIOptionsSnapshotModel(ILogger logger, IOptionsSnapshot fileOptions) 14 | { 15 | _logger = logger; 16 | PdfOptions = fileOptions.Get("pdf"); 17 | DocOptions = fileOptions.Get("doc"); 18 | HtmlOptions = fileOptions.Get("html"); 19 | } 20 | 21 | public void OnGet() 22 | { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

9 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Privacy.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class PrivacyModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public PrivacyModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Providers.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ProvidersModel 3 | @{ 4 | ViewData["Title"] = "Providers"; 5 | } 6 | 7 |
8 |

Providers

9 |
10 | 11 |
    12 | @foreach(var provider in Model.Providers) { 13 |
  • @provider
  • 14 | } 15 |
-------------------------------------------------------------------------------- /12-asp-named/Pages/Providers.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace SampleAsp.Pages; 5 | 6 | public class ProvidersModel : PageModel 7 | { 8 | private IConfigurationRoot ConfigRoot; 9 | private readonly ILogger _logger; 10 | public IEnumerable Providers {get; private set;} 11 | public ProvidersModel(ILogger logger, IConfiguration configRoot) 12 | { 13 | _logger = logger; 14 | ConfigRoot = (IConfigurationRoot)configRoot; 15 | Providers = ConfigRoot.Providers.Select(p => p?.ToString()); 16 | } 17 | 18 | public void OnGet() 19 | { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - SampleAsp 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | 39 |
40 |
41 | © 2022 - SampleAsp - Privacy 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | @await RenderSectionAsync("Scripts", required: false) 50 | 51 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /12-asp-named/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /12-asp-named/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using SampleAsp 2 | @namespace SampleAsp.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /12-asp-named/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /12-asp-named/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | // Add services to the container. 4 | builder.Services.Configure("pdf", 5 | builder.Configuration.GetSection("MarkdownConverter:pdf")); 6 | builder.Services.Configure("doc", 7 | builder.Configuration.GetSection("MarkdownConverter:doc")); 8 | builder.Services.Configure("html", 9 | builder.Configuration.GetSection("MarkdownConverter:html")); 10 | builder.Services.AddRazorPages(); 11 | 12 | var app = builder.Build(); 13 | 14 | // Configure the HTTP request pipeline. 15 | if (!app.Environment.IsDevelopment()) 16 | { 17 | app.UseExceptionHandler("/Error"); 18 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 19 | app.UseHsts(); 20 | } 21 | 22 | app.UseHttpsRedirection(); 23 | app.UseStaticFiles(); 24 | 25 | app.UseRouting(); 26 | 27 | app.UseAuthorization(); 28 | 29 | app.MapRazorPages(); 30 | 31 | app.Run(); 32 | -------------------------------------------------------------------------------- /12-asp-named/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:45522", 7 | "sslPort": 44316 8 | } 9 | }, 10 | "profiles": { 11 | "SampleAsp": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "https://localhost:7229;http://localhost:5275", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /12-asp-named/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /12-asp-named/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "MarkdownConverter": { 3 | "markdownStyle": "github", 4 | "pdf": { 5 | "FileExtension": "pdf", 6 | "OutputDir": "./output/pdf/", 7 | "TemplateFile": "./templates/template.pdf" 8 | }, 9 | "doc": { 10 | "FileExtension": "doc", 11 | "OutputDir": "./output/doc/", 12 | "TemplateFile": "./templates/template.doc" 13 | }, 14 | "html": { 15 | "FileExtension": "html", 16 | "OutputDir": "./output/html/", 17 | "TemplateFile": "./templates/template.html" 18 | } 19 | }, 20 | "Logging": { 21 | "LogLevel": { 22 | "Default": "Information", 23 | "Microsoft.AspNetCore": "Warning" 24 | } 25 | }, 26 | "AllowedHosts": "*" 27 | } -------------------------------------------------------------------------------- /12-asp-named/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | html { 7 | font-size: 16px; 8 | } 9 | } 10 | 11 | html { 12 | position: relative; 13 | min-height: 100%; 14 | } 15 | 16 | body { 17 | margin-bottom: 60px; 18 | } -------------------------------------------------------------------------------- /12-asp-named/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/12-asp-named/wwwroot/favicon.ico -------------------------------------------------------------------------------- /12-asp-named/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /12-asp-named/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2021 Twitter, Inc. 4 | Copyright (c) 2011-2021 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /12-asp-named/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::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;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}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[data-bs-original-title],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:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}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:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}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:#6c757d;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]::-webkit-calendar-picker-indicator{display:none}[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]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-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} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /12-asp-named/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /12-asp-named/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /12-asp-named/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /13-app-config-asp/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SampleAppConfigAsp.Models; 4 | 5 | namespace SampleAppConfigAsp.Controllers; 6 | 7 | public class HomeController : Controller 8 | { 9 | private readonly ILogger _logger; 10 | 11 | public HomeController(ILogger logger) 12 | { 13 | _logger = logger; 14 | } 15 | 16 | public IActionResult Index() 17 | { 18 | return View(); 19 | } 20 | 21 | public IActionResult Privacy() 22 | { 23 | return View(); 24 | } 25 | 26 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 27 | public IActionResult Error() 28 | { 29 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /13-app-config-asp/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace SampleAppConfigAsp.Models; 2 | 3 | public class ErrorViewModel 4 | { 5 | public string? RequestId { get; set; } 6 | 7 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 8 | } 9 | -------------------------------------------------------------------------------- /13-app-config-asp/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.Configuration.AzureAppConfiguration; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | var connectionString = builder.Configuration["ConnectionStrings:AppConfig"]; 6 | 7 | //Connect to your App Config Store using the connection string 8 | builder.Configuration.AddAzureAppConfiguration(options => 9 | { 10 | options.Connect(connectionString) 11 | .ConfigureRefresh(refresh => 12 | { 13 | refresh.Register("TestApp:Settings:Sentinel", refreshAll: true) 14 | .SetRefreshInterval(new TimeSpan(0, 0, 5)); 15 | }); 16 | }); 17 | 18 | // Add services to the container. 19 | builder.Services.AddControllersWithViews(); 20 | builder.Services.AddAzureAppConfiguration(); 21 | builder.Services.Configure(builder.Configuration.GetSection("TestApp:Settings")); 22 | 23 | var app = builder.Build(); 24 | 25 | // Configure the HTTP request pipeline. 26 | if (!app.Environment.IsDevelopment()) 27 | { 28 | app.UseExceptionHandler("/Home/Error"); 29 | } 30 | app.UseStaticFiles(); 31 | 32 | app.UseRouting(); 33 | 34 | app.UseAuthorization(); 35 | app.UseAzureAppConfiguration(); 36 | 37 | app.MapControllerRoute( 38 | name: "default", 39 | pattern: "{controller=Home}/{action=Index}/{id?}"); 40 | 41 | app.Run(); 42 | -------------------------------------------------------------------------------- /13-app-config-asp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:22385", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "SampleAppConfigAsp": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "http://localhost:5043", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /13-app-config-asp/SamplAppConfigAsp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 2d3ed947-36c1-4d6f-afaf-48e661f4d837 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /13-app-config-asp/Settings.cs: -------------------------------------------------------------------------------- 1 | public class Settings 2 | { 3 | public string BackgroundColor { get; set; } = string.Empty; 4 | public string FontColor { get; set; } = string.Empty; 5 | public int FontSize { get; set; } 6 | public string Message { get; set; } = string.Empty; 7 | public string Sentinel { get; set; } = string.Empty; 8 | } -------------------------------------------------------------------------------- /13-app-config-asp/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.Extensions.Configuration 2 | @inject IConfiguration Configuration 3 | 4 | 13 | 14 |

@Configuration["TestApp:Settings:Message"]

-------------------------------------------------------------------------------- /13-app-config-asp/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

Use this page to detail your site's privacy policy.

7 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model?.ShowRequestId ?? false) 10 | { 11 |

12 | Request ID: @Model?.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - SampleAppConfigAsp 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | 39 |
40 |
41 | © 2022 - SampleAppConfigAsp - Privacy 42 |
43 |
44 | 45 | 46 | 47 | @await RenderSectionAsync("Scripts", required: false) 48 | 49 | 50 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using SampleAppConfigAsp 2 | @using SampleAppConfigAsp.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /13-app-config-asp/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /13-app-config-asp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /13-app-config-asp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /13-app-config-asp/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | location=eastus 4 | rg=rg-dotnet 5 | acName=cayers-dotnet-ac 6 | 7 | az group create --name ${rg} --location ${location} 8 | 9 | az appconfig create --location ${location} --name ${acName} --resource-group ${rg} 10 | 11 | az appconfig kv set --name ${acName} --key TestApp:Settings:BackgroundColor --value White -y 12 | az appconfig kv set --name ${acName} --key TestApp:Settings:FontColor --value Black -y 13 | az appconfig kv set --name ${acName} --key TestApp:Settings:FontSize --value 40 -y 14 | az appconfig kv set --name ${acName} --key TestApp:Settings:Message --value "Data from Azure App Configuration" -y 15 | az appconfig kv set --name ${acName} --key TestApp:Settings:Sentinel --value 1 -y 16 | 17 | dotnet user-secrets set ConnectionStrings:AppConfig $(az appconfig credential list -g $rg -n $acName --query "([?name=='Primary Read Only'].connectionString)[0]" --output tsv) -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | html { 7 | font-size: 16px; 8 | } 9 | } 10 | 11 | html { 12 | position: relative; 13 | min-height: 100%; 14 | } 15 | 16 | body { 17 | margin-bottom: 60px; 18 | } -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/13-app-config-asp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2021 Twitter, Inc. 4 | Copyright (c) 2011-2021 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /13-app-config-asp/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /14-validation/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /14-validation/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace Validation.Pages; 6 | 7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 8 | [IgnoreAntiforgeryToken] 9 | public class ErrorModel : PageModel 10 | { 11 | public string? RequestId { get; set; } 12 | 13 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 14 | 15 | private readonly ILogger _logger; 16 | 17 | public ErrorModel(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public void OnGet() 23 | { 24 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /14-validation/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | -------------------------------------------------------------------------------- /14-validation/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace Validation.Pages; 5 | 6 | public class IndexModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public IndexModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /14-validation/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

9 | -------------------------------------------------------------------------------- /14-validation/Pages/Privacy.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace Validation.Pages; 5 | 6 | public class PrivacyModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public PrivacyModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /14-validation/Pages/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - Validation 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | 39 |
40 |
41 | © 2022 - Validation - Privacy 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | @await RenderSectionAsync("Scripts", required: false) 50 | 51 | -------------------------------------------------------------------------------- /14-validation/Pages/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /14-validation/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /14-validation/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Validation 2 | @namespace Validation.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /14-validation/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /14-validation/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection.Extensions; 2 | using Microsoft.Extensions.Options; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | var builder = WebApplication.CreateBuilder(args); 6 | 7 | builder.Services.AddOptions() 8 | .BindConfiguration(WebHookSettings.ConfigurationSectionName) 9 | .ValidateDataAnnotations() 10 | .Validate(config => 11 | { 12 | if (config.WebhookUrl.Length < 20) 13 | { 14 | return false; 15 | } 16 | 17 | return true; 18 | }, "URL length is too short.") 19 | .Validate(webHookSettings => 20 | { 21 | return webHookSettings.WebhookUrl.StartsWith("https://"); 22 | }, "WebHookUrl must start with https://") 23 | .ValidateOnStart(); 24 | 25 | builder.Services.AddSingleton(resolver => 26 | resolver.GetRequiredService>().Value); 27 | 28 | builder.Services.TryAddEnumerable( 29 | ServiceDescriptor.Singleton 30 | , ValidateWebHookSettingsOptions>()); 31 | 32 | // Add services to the container. 33 | builder.Services.AddRazorPages(); 34 | 35 | var app = builder.Build(); 36 | 37 | // Configure the HTTP request pipeline. 38 | if (!app.Environment.IsDevelopment()) 39 | { 40 | app.UseExceptionHandler("/Error"); 41 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseHttpsRedirection(); 46 | app.UseStaticFiles(); 47 | 48 | app.UseRouting(); 49 | 50 | app.UseAuthorization(); 51 | 52 | // app.MapRazorPages(); 53 | app.MapGet("/", (WebHookSettings options) => options); 54 | 55 | app.Run(); 56 | -------------------------------------------------------------------------------- /14-validation/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:17030", 7 | "sslPort": 44387 8 | } 9 | }, 10 | "profiles": { 11 | "Validation": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "https://localhost:7090;http://localhost:5268", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /14-validation/ValidateWebHookSettingsOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Text.RegularExpressions; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.Options; 5 | 6 | class ValidateWebHookSettingsOptions : IValidateOptions 7 | { 8 | public WebHookSettings _settings { get; private set; } 9 | 10 | public ValidateWebHookSettingsOptions(IConfiguration config) => 11 | _settings = config?.GetSection(WebHookSettings.ConfigurationSectionName) 12 | .Get() 13 | ?? new WebHookSettings(); 14 | 15 | public ValidateOptionsResult Validate(string? name, WebHookSettings options) 16 | { 17 | StringBuilder failure = new(); 18 | var rx = new Regex(@"^[a-zA-Z''-'\s]{1,20}$"); 19 | Match match = rx.Match(options.DisplayName); 20 | if (string.IsNullOrEmpty(match.Value)) 21 | { 22 | failure.AppendLine($"DisplayName: {options.DisplayName} doesn't match RegEx"); 23 | } 24 | 25 | return failure.Length > 0 26 | ? ValidateOptionsResult.Fail(failure.ToString()) 27 | : ValidateOptionsResult.Success; 28 | } 29 | } -------------------------------------------------------------------------------- /14-validation/Validation.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | Validation 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /14-validation/WebHookSettings.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Text.RegularExpressions; 3 | 4 | public class WebHookSettings 5 | { 6 | public const string ConfigurationSectionName = "WebHook"; 7 | 8 | [Required, Url] 9 | public string WebhookUrl { get; set; } = string.Empty; 10 | 11 | [Required] 12 | [RegularExpression(@"^[a-zA-Z''-'\s]{1,20}$", 13 | ErrorMessage = "DisplayName: {0} doesn't match RegEx")] 14 | public string DisplayName { get; set; } = string.Empty; 15 | 16 | public bool Enabled { get; set; } 17 | 18 | [Required] 19 | [Range(0, 3, 20 | ErrorMessage = "Value for {0} must be between {1} and {2}.")] 21 | public int RetryTimes { get; set; } 22 | } -------------------------------------------------------------------------------- /14-validation/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /14-validation/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "WebHook": { 10 | "WebhookUrl": "https://example.com/event", 11 | "DisplayName": "DevOps", 12 | "Enabled": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /14-validation/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | html { 7 | font-size: 16px; 8 | } 9 | } 10 | 11 | html { 12 | position: relative; 13 | min-height: 100%; 14 | } 15 | 16 | body { 17 | margin-bottom: 60px; 18 | } -------------------------------------------------------------------------------- /14-validation/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/14-validation/wwwroot/favicon.ico -------------------------------------------------------------------------------- /14-validation/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /14-validation/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2021 Twitter, Inc. 4 | Copyright (c) 2011-2021 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /14-validation/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::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;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}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[data-bs-original-title],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:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}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:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}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:#6c757d;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]::-webkit-calendar-picker-indicator{display:none}[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]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-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} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /14-validation/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /14-validation/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /14-validation/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace Validation.Pages; 6 | 7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 8 | [IgnoreAntiforgeryToken] 9 | public class ErrorModel : PageModel 10 | { 11 | public string? RequestId { get; set; } 12 | 13 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 14 | 15 | private readonly ILogger _logger; 16 | 17 | public ErrorModel(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public void OnGet() 23 | { 24 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Welcome

9 |

Learn about building Web apps with ASP.NET Core.

10 |
11 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace Validation.Pages; 5 | 6 | public class IndexModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public IndexModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

9 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Privacy.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | 4 | namespace Validation.Pages; 5 | 6 | public class PrivacyModel : PageModel 7 | { 8 | private readonly ILogger _logger; 9 | 10 | public PrivacyModel(ILogger logger) 11 | { 12 | _logger = logger; 13 | } 14 | 15 | public void OnGet() 16 | { 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - Validation 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 |
33 |
34 |
35 | @RenderBody() 36 |
37 |
38 | 39 |
40 |
41 | © 2022 - Validation - Privacy 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | @await RenderSectionAsync("Scripts", required: false) 50 | 51 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Validation 2 | @namespace Validation.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /15-postconfig-validation/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /15-postconfig-validation/PostValidation.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | Validation 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /15-postconfig-validation/Program.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Microsoft.Extensions.Options; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | builder.Services.AddOptions() 7 | .BindConfiguration("WebHook") 8 | .ValidateDataAnnotations() 9 | .ValidateOnStart(); 10 | 11 | builder.Services.AddSingleton(resolver => 12 | resolver.GetRequiredService>().Value); 13 | 14 | builder.Services.PostConfigure(webHookSettings => 15 | { 16 | // make sure url scheme is https 17 | if (!webHookSettings.WebhookUrl?.StartsWith("https://") ?? false) 18 | { 19 | webHookSettings.WebhookUrl = webHookSettings.WebhookUrl?.Replace("http://", "https://"); 20 | } 21 | }); 22 | 23 | // Add services to the container. 24 | builder.Services.AddRazorPages(); 25 | 26 | var app = builder.Build(); 27 | 28 | // Configure the HTTP request pipeline. 29 | if (!app.Environment.IsDevelopment()) 30 | { 31 | app.UseExceptionHandler("/Error"); 32 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 33 | app.UseHsts(); 34 | } 35 | 36 | app.UseHttpsRedirection(); 37 | app.UseStaticFiles(); 38 | 39 | app.UseRouting(); 40 | 41 | app.UseAuthorization(); 42 | 43 | // app.MapRazorPages(); 44 | app.MapGet("/", (WebHookSettings options) => options); 45 | 46 | app.Run(); 47 | -------------------------------------------------------------------------------- /15-postconfig-validation/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:17030", 7 | "sslPort": 44387 8 | } 9 | }, 10 | "profiles": { 11 | "Validation": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "https://localhost:7090;http://localhost:5268", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /15-postconfig-validation/WebHookSettings.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | public class WebHookSettings 4 | { 5 | [Required, Url] 6 | public string? WebhookUrl { get; set; } = default; 7 | 8 | [Required] 9 | public string? DisplayName { get; set; } = default; 10 | 11 | public bool Enabled { get; set; } 12 | 13 | [Required] 14 | [Range(0, 3, 15 | ErrorMessage = "Value for {0} must be between {1} and {2}.")] 16 | public int RetryTimes { get; set; } 17 | } -------------------------------------------------------------------------------- /15-postconfig-validation/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /15-postconfig-validation/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "WebHook": { 10 | "WebhookUrl": "http://example.com/event", 11 | "DisplayName": "DevOps", 12 | "Enabled": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | html { 7 | font-size: 16px; 8 | } 9 | } 10 | 11 | html { 12 | position: relative; 13 | min-height: 100%; 14 | } 15 | 16 | body { 17 | margin-bottom: 60px; 18 | } -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/15-postconfig-validation/wwwroot/favicon.ico -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2021 Twitter, Inc. 4 | Copyright (c) 2011-2021 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /15-postconfig-validation/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ApiService/16-aspire.ApiService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ApiService/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | // Add service defaults & Aspire client integrations. 4 | builder.AddServiceDefaults(); 5 | 6 | // Add services to the container. 7 | builder.Services.AddProblemDetails(); 8 | 9 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 10 | builder.Services.AddOpenApi(); 11 | 12 | var app = builder.Build(); 13 | 14 | // Configure the HTTP request pipeline. 15 | app.UseExceptionHandler(); 16 | 17 | if (app.Environment.IsDevelopment()) 18 | { 19 | app.MapOpenApi(); 20 | } 21 | 22 | string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"]; 23 | 24 | app.MapGet("/weatherforecast", () => 25 | { 26 | var forecast = Enumerable.Range(1, 5).Select(index => 27 | new WeatherForecast 28 | ( 29 | DateOnly.FromDateTime(DateTime.Now.AddDays(index)), 30 | Random.Shared.Next(-20, 55), 31 | summaries[Random.Shared.Next(summaries.Length)] 32 | )) 33 | .ToArray(); 34 | return forecast; 35 | }) 36 | .WithName("GetWeatherForecast"); 37 | 38 | app.MapDefaultEndpoints(); 39 | 40 | app.Run(); 41 | 42 | record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 43 | { 44 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 45 | } 46 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ApiService/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:5461", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": false, 17 | "applicationUrl": "https://localhost:7370;http://localhost:5461", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ApiService/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ApiService/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.AppHost/16-aspire.AppHost.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Exe 7 | net9.0 8 | enable 9 | enable 10 | true 11 | 52caef68-e049-41e7-a21a-b02a0eef999d 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.AppHost/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = DistributedApplication.CreateBuilder(args); 2 | 3 | var apiService = builder.AddProject("apiservice"); 4 | 5 | builder.AddProject("webfrontend") 6 | .WithExternalHttpEndpoints() 7 | .WithReference(apiService) 8 | .WaitFor(apiService); 9 | 10 | builder.Build().Run(); 11 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.AppHost/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 | "applicationUrl": "https://localhost:17245;http://localhost:15063", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development", 11 | "DOTNET_ENVIRONMENT": "Development", 12 | "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21050", 13 | "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22157" 14 | } 15 | }, 16 | "http": { 17 | "commandName": "Project", 18 | "dotnetRunMessages": true, 19 | "launchBrowser": true, 20 | "applicationUrl": "http://localhost:15063", 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development", 23 | "DOTNET_ENVIRONMENT": "Development", 24 | "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19276", 25 | "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20162" 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.AppHost/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.AppHost/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning", 6 | "Aspire.Hosting.Dcp": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.ServiceDefaults/16-aspire.ServiceDefaults.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/16-aspire.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/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 | 79 | #blazor-error-ui { 80 | background: lightyellow; 81 | bottom: 0; 82 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 83 | display: none; 84 | left: 0; 85 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 86 | position: fixed; 87 | width: 100%; 88 | z-index: 1000; 89 | } 90 | 91 | #blazor-error-ui .dismiss { 92 | cursor: pointer; 93 | position: absolute; 94 | right: 0.75rem; 95 | top: 0.5rem; 96 | } 97 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Layout/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 30 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Layout/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | appearance: none; 3 | cursor: pointer; 4 | width: 3.5rem; 5 | height: 2.5rem; 6 | color: white; 7 | position: absolute; 8 | top: 0.5rem; 9 | right: 1rem; 10 | border: 1px solid rgba(255, 255, 255, 0.1); 11 | background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1); 12 | } 13 | 14 | .navbar-toggler:checked { 15 | background-color: rgba(255, 255, 255, 0.5); 16 | } 17 | 18 | .top-row { 19 | min-height: 3.5rem; 20 | background-color: rgba(0,0,0,0.4); 21 | } 22 | 23 | .navbar-brand { 24 | font-size: 1.1rem; 25 | } 26 | 27 | .bi { 28 | display: inline-block; 29 | position: relative; 30 | width: 1.25rem; 31 | height: 1.25rem; 32 | margin-right: 0.75rem; 33 | top: -1px; 34 | background-size: cover; 35 | } 36 | 37 | .bi-house-door-fill { 38 | 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"); 39 | } 40 | 41 | .bi-plus-square-fill { 42 | 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"); 43 | } 44 | 45 | .bi-list-nested { 46 | 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"); 47 | } 48 | 49 | .nav-item { 50 | font-size: 0.9rem; 51 | padding-bottom: 0.5rem; 52 | } 53 | 54 | .nav-item:first-of-type { 55 | padding-top: 1rem; 56 | } 57 | 58 | .nav-item:last-of-type { 59 | padding-bottom: 1rem; 60 | } 61 | 62 | .nav-item ::deep a { 63 | color: #d7d7d7; 64 | border-radius: 4px; 65 | height: 3rem; 66 | display: flex; 67 | align-items: center; 68 | line-height: 3rem; 69 | } 70 | 71 | .nav-item ::deep a.active { 72 | background-color: rgba(255,255,255,0.37); 73 | color: white; 74 | } 75 | 76 | .nav-item ::deep a:hover { 77 | background-color: rgba(255,255,255,0.1); 78 | color: white; 79 | } 80 | 81 | .nav-scrollable { 82 | display: none; 83 | } 84 | 85 | .navbar-toggler:checked ~ .nav-scrollable { 86 | display: block; 87 | } 88 | 89 | @media (min-width: 641px) { 90 | .navbar-toggler { 91 | display: none; 92 | } 93 | 94 | .nav-scrollable { 95 | /* Never collapse the sidebar for wide screens */ 96 | display: block; 97 | 98 | /* Allow sidebar to scroll for tall menus */ 99 | height: calc(100vh - 3.5rem); 100 | overflow-y: auto; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | @rendermode InteractiveServer 3 | 4 | Counter 5 | 6 |

Counter

7 | 8 |

Current count: @currentCount

9 | 10 | 11 | 12 | @code { 13 | private int currentCount = 0; 14 | 15 | private void IncrementCount() 16 | { 17 | currentCount++; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Pages/Error.razor: -------------------------------------------------------------------------------- 1 | @page "/Error" 2 | @using System.Diagnostics 3 | 4 | Error 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (ShowRequestId) 10 | { 11 |

12 | Request ID: @requestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | 27 | @code{ 28 | [CascadingParameter] 29 | public HttpContext? HttpContext { get; set; } 30 | 31 | private string? requestId; 32 | private bool ShowRequestId => !string.IsNullOrEmpty(requestId); 33 | 34 | protected override void OnInitialized() 35 | { 36 | requestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Pages/Weather.razor: -------------------------------------------------------------------------------- 1 | @page "/weather" 2 | @attribute [StreamRendering(true)] 3 | @attribute [OutputCache(Duration = 5)] 4 | 5 | @inject WeatherApiClient WeatherApi 6 | 7 | Weather 8 | 9 |

Weather

10 | 11 |

This component demonstrates showing data loaded from a backend API service.

12 | 13 | @if (forecasts == null) 14 | { 15 |

Loading...

16 | } 17 | else 18 | { 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | @foreach (var forecast in forecasts) 30 | { 31 | 32 | 33 | 34 | 35 | 36 | 37 | } 38 | 39 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
40 | } 41 | 42 | @code { 43 | private WeatherForecast[]? forecasts; 44 | 45 | protected override async Task OnInitializedAsync() 46 | { 47 | forecasts = await WeatherApi.GetWeatherAsync(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Components/_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 static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.AspNetCore.OutputCaching 9 | @using Microsoft.JSInterop 10 | @using _16_aspire.Web 11 | @using _16_aspire.Web.Components 12 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using _16_aspire.Web; 2 | using _16_aspire.Web.Components; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | // Add service defaults & Aspire client integrations. 7 | builder.AddServiceDefaults(); 8 | 9 | // Add services to the container. 10 | builder.Services.AddRazorComponents() 11 | .AddInteractiveServerComponents(); 12 | 13 | builder.Services.AddOutputCache(); 14 | 15 | builder.Services.AddHttpClient(client => 16 | { 17 | // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP. 18 | // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes. 19 | client.BaseAddress = new("https+http://apiservice"); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | if (!app.Environment.IsDevelopment()) 25 | { 26 | app.UseExceptionHandler("/Error", createScopeForErrors: true); 27 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 28 | app.UseHsts(); 29 | } 30 | 31 | app.UseHttpsRedirection(); 32 | 33 | app.UseAntiforgery(); 34 | 35 | app.UseOutputCache(); 36 | 37 | app.MapStaticAssets(); 38 | 39 | app.MapRazorComponents() 40 | .AddInteractiveServerRenderMode(); 41 | 42 | app.MapDefaultEndpoints(); 43 | 44 | app.Run(); 45 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/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 | "applicationUrl": "http://localhost:5073", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7145;http://localhost:5073", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/WeatherApiClient.cs: -------------------------------------------------------------------------------- 1 | namespace _16_aspire.Web; 2 | 3 | public class WeatherApiClient(HttpClient httpClient) 4 | { 5 | public async Task GetWeatherAsync(int maxItems = 10, CancellationToken cancellationToken = default) 6 | { 7 | List? forecasts = null; 8 | 9 | await foreach (var forecast in httpClient.GetFromJsonAsAsyncEnumerable("/weatherforecast", cancellationToken)) 10 | { 11 | if (forecasts?.Count >= maxItems) 12 | { 13 | break; 14 | } 15 | if (forecast is not null) 16 | { 17 | forecasts ??= []; 18 | forecasts.Add(forecast); 19 | } 20 | } 21 | 22 | return forecasts?.ToArray() ?? []; 23 | } 24 | } 25 | 26 | public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 27 | { 28 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 29 | } 30 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/wwwroot/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 3 | } 4 | 5 | a, .btn-link { 6 | color: #006bb7; 7 | } 8 | 9 | .btn-primary { 10 | color: #fff; 11 | background-color: #1b6ec2; 12 | border-color: #1861ac; 13 | } 14 | 15 | .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { 16 | box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; 17 | } 18 | 19 | .content { 20 | padding-top: 1.1rem; 21 | } 22 | 23 | h1:focus { 24 | outline: none; 25 | } 26 | 27 | .valid.modified:not([type=checkbox]) { 28 | outline: 1px solid #26b050; 29 | } 30 | 31 | .invalid { 32 | outline: 1px solid #e50730; 33 | } 34 | 35 | .validation-message { 36 | color: #e50730; 37 | } 38 | 39 | .blazor-error-boundary { 40 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 41 | padding: 1rem 1rem 1rem 3.7rem; 42 | color: white; 43 | } 44 | 45 | .blazor-error-boundary::after { 46 | content: "An error has occurred." 47 | } 48 | 49 | .form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { 50 | color: var(--bs-secondary-color); 51 | text-align: end; 52 | } 53 | 54 | .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { 55 | text-align: start; 56 | } 57 | -------------------------------------------------------------------------------- /16-aspire/16-aspire.Web/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/16-aspire/16-aspire.Web/wwwroot/favicon.png -------------------------------------------------------------------------------- /16-aspire/16-aspire.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.8.0.0 4 | MinimumVisualStudioVersion = 17.8.0.0 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "16-aspire.AppHost", "16-aspire.AppHost\16-aspire.AppHost.csproj", "{5697F871-0921-4541-B764-1D8F4A0A3FD8}" 6 | EndProject 7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "16-aspire.ServiceDefaults", "16-aspire.ServiceDefaults\16-aspire.ServiceDefaults.csproj", "{0C45143A-2B9C-4254-B51E-09CF36258156}" 8 | EndProject 9 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "16-aspire.ApiService", "16-aspire.ApiService\16-aspire.ApiService.csproj", "{DDCA65F0-F8DA-4EF6-89CB-7FAE632C4CDA}" 10 | EndProject 11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "16-aspire.Web", "16-aspire.Web\16-aspire.Web.csproj", "{679E3834-C628-4327-879F-F6070310A6A9}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {5697F871-0921-4541-B764-1D8F4A0A3FD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {5697F871-0921-4541-B764-1D8F4A0A3FD8}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {5697F871-0921-4541-B764-1D8F4A0A3FD8}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {5697F871-0921-4541-B764-1D8F4A0A3FD8}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {0C45143A-2B9C-4254-B51E-09CF36258156}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {0C45143A-2B9C-4254-B51E-09CF36258156}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {0C45143A-2B9C-4254-B51E-09CF36258156}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {0C45143A-2B9C-4254-B51E-09CF36258156}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {DDCA65F0-F8DA-4EF6-89CB-7FAE632C4CDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {DDCA65F0-F8DA-4EF6-89CB-7FAE632C4CDA}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {DDCA65F0-F8DA-4EF6-89CB-7FAE632C4CDA}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {DDCA65F0-F8DA-4EF6-89CB-7FAE632C4CDA}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {679E3834-C628-4327-879F-F6070310A6A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {679E3834-C628-4327-879F-F6070310A6A9}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {679E3834-C628-4327-879F-F6070310A6A9}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {679E3834-C628-4327-879F-F6070310A6A9}.Release|Any CPU.Build.0 = Release|Any CPU 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | GlobalSection(ExtensibilityGlobals) = postSolution 40 | SolutionGuid = {2F626630-BB85-4120-A7AD-2706746B5FA0} 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # .NET Configuration in Depth 2 | 3 | This repository contains the slide deck, demos, and resources for the ".NET Configuration in Depth" talk by Chris Ayers, Senior Customer Engineer at Microsoft. The talk provides an in-depth look at .NET configuration, configuration providers, binding, and the options pattern. 4 | 5 | ## Slides 6 | 7 | You can access the slides for the talk at the following link: 8 | 9 | - [https://chris-ayers.com/dotnet-configuration-in-depth/](https://chris-ayers.com/dotnet-configuration-in-depth/) 10 | 11 | ## Demos and Resources 12 | 13 | The repository includes a variety of demos and resources to demonstrate the use of .NET configuration in different scenarios. These demos and resources can help you understand how to implement .NET configuration best practices effectively and take advantage of the available tools. 14 | 15 | ## Related Blog Posts 16 | 17 | For a more detailed understanding of the topics covered in this talk and the related demos, you can read the following blog posts: 18 | 19 | - [Validating .NET Configuration](https://chris-ayers.com/2022/12/03/validating-dotnet-configuration) 20 | 21 | ## Resources 22 | 23 | For more information on .NET configuration, configuration providers, and the options pattern, you can refer to the following resources: 24 | 25 | - [.NET Configuration Documentation](https://docs.microsoft.com/en-us/dotnet/core/extensions/configuration) 26 | - [Configuration Providers in .NET](https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration-providers) 27 | - [Configuration in ASP.NET](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/) 28 | - [Options pattern in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options) 29 | - [Azure App Configuration](https://docs.microsoft.com/en-us/azure/azure-app-configuration/) 30 | - [Azure Key Vault Configuration Provider](https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration) 31 | 32 | ## Connect with Chris Ayers 33 | 34 | Feel free to connect with Chris Ayers on social media and visit his blog for more information on .NET configuration, security, and other topics: 35 | 36 | - Twitter: [@Chris_L_Ayers](https://twitter.com/Chris_L_Ayers) 37 | - Mastodon: [@Chrisayers@hachyderm.io](https://hachyderm.io/@Chrisayers) 38 | - LinkedIn: [chris-l-ayers](https://linkedin.com/in/chris-l-ayers/) 39 | - Blog: [https://chris-ayers.com/](https://chris-ayers.com/) 40 | - GitHub: [Codebytes](https://github.com/codebytes) 41 | 42 | ## License 43 | 44 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information. 45 | -------------------------------------------------------------------------------- /slides/img/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/background.jpg -------------------------------------------------------------------------------- /slides/img/coding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/coding.png -------------------------------------------------------------------------------- /slides/img/compile-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/compile-time.png -------------------------------------------------------------------------------- /slides/img/configuration-providers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/configuration-providers.png -------------------------------------------------------------------------------- /slides/img/configuration-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/configuration-source.png -------------------------------------------------------------------------------- /slides/img/dotnet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/dotnet-logo.png -------------------------------------------------------------------------------- /slides/img/gears.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/gears.png -------------------------------------------------------------------------------- /slides/img/owl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/owl.png -------------------------------------------------------------------------------- /slides/img/portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/portrait.jpg -------------------------------------------------------------------------------- /slides/img/portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/portrait.png -------------------------------------------------------------------------------- /slides/img/run-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/run-time.png -------------------------------------------------------------------------------- /slides/img/session-feedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebytes/dotnet-configuration-in-depth/9dff1f2b5be675caf5eb9e0e7d106b6a36de450b/slides/img/session-feedback.png -------------------------------------------------------------------------------- /slides/themes/custom-default.css: -------------------------------------------------------------------------------- 1 | /* custom-default.css */ 2 | /* @theme custom-default */ 3 | 4 | @import 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css'; 5 | @import 'default'; 6 | 7 | .columns { 8 | display: grid; 9 | grid-template-columns: repeat(2, minmax(0, 1fr)); 10 | gap: 1rem; 11 | } 12 | .columns21 { 13 | display: grid; 14 | grid-template-columns: 3fr 2fr; 15 | gap: 1rem; 16 | } 17 | .columns3 { 18 | display: grid; 19 | grid-template-columns: repeat(3, minmax(0, 1fr)); 20 | gap: 1rem; 21 | } 22 | img[alt~="center"] { 23 | display: block; 24 | margin: 0 auto; 25 | } 26 | .fa-twitter { color: aqua; } 27 | .fa-mastodon { color: purple; } 28 | .fa-linkedin { color: blue; } 29 | .fa-window-maximize { color: skyblue; } 30 | .fa-bluesky { color: skyblue; } 31 | 32 | svg[id^="mermaid-"] { 33 | max-width: 960px; 34 | max-height: 600px; 35 | } 36 | 37 | @import 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css' --------------------------------------------------------------------------------