From 3aeee5354c4403ef079adee631f6fa0474285381 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:00:44 -1000 Subject: [PATCH] Add new bind sample /8 (#30882) * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 * Add new bind sample /8 --- .../8.x/ConfigSample/ConfigSample.csproj | 2 +- .../8.x/ConfigSample/Options/ArrayExample.cs | 13 +++-- .../MyConfigServiceCollectionExtensions.cs | 1 + .../ConfigSample/Options/NameTitleOptions.cs | 16 ++++++ .../ConfigSample/Options/PositionOptions.cs | 17 +++--- .../8.x/ConfigSample/Pages/Array.cshtml.cs | 44 ++++++++-------- .../8.x/ConfigSample/Pages/Index2.cshtml.cs | 6 +-- .../8.x/ConfigSample/Pages/Test21.cshtml.cs | 37 +++++++------ .../8.x/ConfigSample/Pages/Test33.cshtml | 4 ++ .../8.x/ConfigSample/Pages/Test33.cshtml.cs | 28 ++++++++++ .../8.x/ConfigSample/Pages/TestNum.cshtml.cs | 8 +-- .../ConfigSample/Pages/TestSection.cshtml.cs | 8 +-- .../ConfigSample/Pages/TestSection2.cshtml.cs | 8 +-- .../ConfigSample/Pages/TestSection4.cshtml.cs | 8 +-- .../ConfigSample/Pages/XML/Index.cshtml.cs | 52 +++++++++---------- .../index/samples/8.x/ConfigSample/Program.cs | 5 +- .../ConfigSample/appsettings.Development.json | 5 ++ aspnetcore/includes/bind7.md | 15 ++++++ 18 files changed, 173 insertions(+), 104 deletions(-) create mode 100644 aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs create mode 100644 aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml create mode 100644 aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/ConfigSample.csproj b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/ConfigSample.csproj index 9a214e2071c1..f18b55737643 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/ConfigSample.csproj +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/ConfigSample.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/ArrayExample.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/ArrayExample.cs index 5d3d2074df62..90346466c06d 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/ArrayExample.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/ArrayExample.cs @@ -1,9 +1,8 @@ -namespace ConfigSample.Options +namespace ConfigSample.Options; + +// +public class ArrayExample { - #region snippet - public class ArrayExample - { - public string[]? Entries { get; set; } - } - #endregion + public string[]? Entries { get; set; } } +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs index 55be42dcc302..02a8a4807dc5 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs @@ -1,5 +1,6 @@ using ConfigSample.Options; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection.ConfigSample.Options; namespace Microsoft.Extensions.DependencyInjection { diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs new file mode 100644 index 000000000000..85e591c72712 --- /dev/null +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs @@ -0,0 +1,16 @@ +namespace ConfigSample.Options; + +public abstract class SomethingWithAName +{ + public abstract string? Name { get; set; } +} + +public class NameTitleOptions(int age) : SomethingWithAName +{ + public const string NameTitle = "NameTitle"; + + public override string? Name { get; set; } + public string Title { get; set; } = string.Empty; + + public int Age { get; set; } = age; +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/PositionOptions.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/PositionOptions.cs index 8f6aad2f139b..b8377543cbf0 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/PositionOptions.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/PositionOptions.cs @@ -1,12 +1,11 @@ -namespace ConfigSample.Options +namespace ConfigSample.Options; + +// +public class PositionOptions { - #region snippet - public class PositionOptions - { - public const string Position = "Position"; + public const string Position = "Position"; - public string Title { get; set; } = String.Empty; - public string Name { get; set; } = String.Empty; - } - #endregion + public string Title { get; set; } = String.Empty; + public string Name { get; set; } = String.Empty; } +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Array.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Array.cshtml.cs index 27557ccfd4a8..481f32272f68 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Array.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Array.cshtml.cs @@ -1,37 +1,35 @@ using ConfigSample.Options; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Configuration; -namespace ConfigSample -{ +namespace ConfigSample; + // - public class ArrayModel : PageModel +public class ArrayModel : PageModel +{ + private readonly IConfiguration Config; + public ArrayExample? _array { get; private set; } + + public ArrayModel(IConfiguration config) { - private readonly IConfiguration Config; - public ArrayExample? _array { get; private set; } + Config = config; + } - public ArrayModel(IConfiguration config) + public ContentResult OnGet() + { + _array = Config.GetSection("array").Get(); + if (_array == null || _array.Entries != null) { - Config = config; + throw new ArgumentNullException(nameof(_array)); } + string s = String.Empty; - public ContentResult OnGet() + for (int j = 0; j < _array.Entries!.Length; j++) { - _array = Config.GetSection("array").Get(); - if (_array == null) - { - throw new ArgumentNullException(nameof(_array)); - } - string s = String.Empty; - - for (int j = 0; j < _array.Entries.Length; j++) - { - s += $"Index: {j} Value: {_array.Entries[j]} \n"; - } - - return Content(s); + s += $"Index: {j} Value: {_array.Entries[j]} \n"; } + + return Content(s); } -// } +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Index2.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Index2.cshtml.cs index d101a37c6a3f..df22de6063fd 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Index2.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Index2.cshtml.cs @@ -1,11 +1,11 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; using System.Linq; namespace ConfigSample.Pages { - #region snippet +// public class Index2Model : PageModel { private IConfigurationRoot ConfigRoot; @@ -26,5 +26,5 @@ public ContentResult OnGet() return Content(str); } } - #endregion +// } diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test21.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test21.cshtml.cs index 2c1d6ec4b001..a10862b021f1 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test21.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test21.cshtml.cs @@ -1,29 +1,32 @@ using ConfigSample.Options; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Configuration; -namespace ConfigSample.Pages -{ +namespace ConfigSample.Pages; + // - public class Test21Model : PageModel +public class Test21Model : PageModel +{ + private readonly IConfiguration Configuration; + public PositionOptions? positionOptions { get; private set; } + + public Test21Model(IConfiguration configuration) { - private readonly IConfiguration Configuration; - public PositionOptions? positionOptions { get; private set; } + Configuration = configuration; + } - public Test21Model(IConfiguration configuration) + public ContentResult OnGet() + { + positionOptions = Configuration.GetSection(PositionOptions.Position) + .Get(); + + if (positionOptions == null) { - Configuration = configuration; + throw new ArgumentNullException(nameof(positionOptions)); } - public ContentResult OnGet() - { - positionOptions = Configuration.GetSection(PositionOptions.Position) - .Get(); - - return Content($"Title: {positionOptions.Title} \n" + - $"Name: {positionOptions.Name}"); - } + return Content($"Title: {positionOptions.Title} \n" + + $"Name: {positionOptions.Name}"); } -// } +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml new file mode 100644 index 000000000000..75c0b92c90e3 --- /dev/null +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml @@ -0,0 +1,4 @@ +@page +@model ConfigSample.Pages.Test33Model +@{ +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs new file mode 100644 index 000000000000..2c03cdeb1476 --- /dev/null +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs @@ -0,0 +1,28 @@ +using ConfigSample.Options; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace ConfigSample.Pages; + +// +public class Test33Model : PageModel +{ + private readonly IConfiguration Configuration; + + public Test33Model(IConfiguration configuration) + { + Configuration = configuration; + } + + public ContentResult OnGet() + { + var nameTitleOptions = new NameTitleOptions(22); + Configuration.GetSection(NameTitleOptions.NameTitle).Bind(nameTitleOptions); + + return Content($"Title: {nameTitleOptions.Title} \n" + + $"Name: {nameTitleOptions.Name} \n" + + $"Age: {nameTitleOptions.Age}" + ); + } +} +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestNum.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestNum.cshtml.cs index cd81db82044c..0feec1ce471d 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestNum.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestNum.cshtml.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; @@ -6,7 +6,7 @@ namespace ConfigSample { - #region snippet +// public class TestNumModel : PageModel { private readonly IConfiguration Configuration; @@ -22,5 +22,5 @@ public ContentResult OnGet() return Content($"{number}"); } } - #endregion -} \ No newline at end of file +// +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection.cshtml.cs index 819b4986f83a..762f29be4813 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection.cshtml.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; @@ -6,7 +6,7 @@ namespace ConfigSample { - #region snippet +// public class TestSectionModel : PageModel { private readonly IConfiguration Config; @@ -23,5 +23,5 @@ public ContentResult OnGet() $"section1:key1: '{Config["key1"]}'"); } } - #endregion -} \ No newline at end of file +// +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection2.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection2.cshtml.cs index e5a000668565..5d3f864e8d43 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection2.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection2.cshtml.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; @@ -6,7 +6,7 @@ namespace ConfigSample { - #region snippet +// public class TestSection2Model : PageModel { private readonly IConfiguration Config; @@ -23,5 +23,5 @@ public ContentResult OnGet() $"section2:subsection0:key1:'{Config["key1"]}'"); } } - #endregion -} \ No newline at end of file +// +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection4.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection4.cshtml.cs index a353957cb725..6275eabdd22d 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection4.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/TestSection4.cshtml.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; @@ -6,7 +6,7 @@ namespace ConfigSample { - #region snippet +// public class TestSection4Model : PageModel { private readonly IConfiguration Config; @@ -37,5 +37,5 @@ public ContentResult OnGet() return Content(s); } } - #endregion -} \ No newline at end of file +// +} diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/XML/Index.cshtml.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/XML/Index.cshtml.cs index 9eeb15c17bdd..c382fba1c6a5 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/XML/Index.cshtml.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/XML/Index.cshtml.cs @@ -1,37 +1,35 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Configuration; -namespace ConfigSample.Pages.JSON +namespace ConfigSample.Pages.JSON; + +// +public class IndexModel : PageModel { - #region snippet - public class IndexModel : PageModel - { - private readonly IConfiguration Configuration; + private readonly IConfiguration Configuration; - public IndexModel(IConfiguration configuration) - { - Configuration = configuration; - } + public IndexModel(IConfiguration configuration) + { + Configuration = configuration; + } - public ContentResult OnGet() - { - var key00 = "section:section0:key:key0"; - var key01 = "section:section0:key:key1"; - var key10 = "section:section1:key:key0"; - var key11 = "section:section1:key:key1"; + public ContentResult OnGet() + { + var key00 = "section:section0:key:key0"; + var key01 = "section:section0:key:key1"; + var key10 = "section:section1:key:key0"; + var key11 = "section:section1:key:key1"; - var val00 = Configuration[key00]; - var val01 = Configuration[key01]; - var val10 = Configuration[key10]; - var val11 = Configuration[key11]; + var val00 = Configuration[key00]; + var val01 = Configuration[key01]; + var val10 = Configuration[key10]; + var val11 = Configuration[key11]; - return Content($"{key00} value: {val00} \n" + - $"{key01} value: {val01} \n" + - $"{key10} value: {val10} \n" + - $"{key10} value: {val11} \n" - ); - } + return Content($"{key00} value: {val00} \n" + + $"{key01} value: {val01} \n" + + $"{key10} value: {val10} \n" + + $"{key10} value: {val11} \n" + ); } - #endregion } +// diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Program.cs b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Program.cs index 6ecf910de7b3..c9bcd256b52f 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Program.cs +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/Program.cs @@ -1,4 +1,4 @@ -#define DEFAULT // CONFIG DEFAULT Second Third SWITCH JSON1 INI XML MEM SUB RAY BA RP +#define CONFIG // CONFIG DEFAULT Second Third SWITCH JSON1 INI XML MEM SUB RAY BA RP #if DEFAULT var builder = WebApplication.CreateBuilder(args); @@ -33,6 +33,9 @@ builder.Services.Configure( builder.Configuration.GetSection(PositionOptions.Position)); +builder.Services.Configure( + builder.Configuration.GetSection(NameTitleOptions.NameTitle)); + var app = builder.Build(); // diff --git a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/appsettings.Development.json b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/appsettings.Development.json index abc42901bbd1..61fc8b7c06f6 100644 --- a/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/appsettings.Development.json +++ b/aspnetcore/fundamentals/configuration/index/samples/8.x/ConfigSample/appsettings.Development.json @@ -4,6 +4,11 @@ "Title": "Debug writer", "Name": "Debug Smith" }, + "NameTitle": { + "Title": "NameTitle writer", + "Name": "NT Smith", + "Age": "42" + }, "Color": { "Foreground": "Debug Green-brown", "Background": "Debug Red" diff --git a/aspnetcore/includes/bind7.md b/aspnetcore/includes/bind7.md index 3cfed2227a49..620c63b704d2 100644 --- a/aspnetcore/includes/bind7.md +++ b/aspnetcore/includes/bind7.md @@ -33,6 +33,21 @@ In the preceding code, by default, changes to the JSON configuration file after In the preceding code, by default, changes to the JSON configuration file after the app has started are read. +Bind also allows the concretion of an abstract class. Consider the following code which uses the abstract class `SomethingWithAName`: + +[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs)] + +The following code displays the `NameTitleOptions` configuration values: + +[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs?name=snippet)] + +Calls to `Bind` are less strict than calls to `Get<>`: + +* `Bind` allows the concretion of an abstract. +* `Get<>` has to create an instance itself. + +## The Options Pattern + An alternative approach when using the ***options pattern*** is to bind the `Position` section and add it to the [dependency injection service container](xref:fundamentals/dependency-injection). In the following code, `PositionOptions` is added to the service container with and bound to configuration: [!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)]