Settings

Settings are stored inside the “appsettings.json” file within the root of the “*.Web” project. You can have environment specific settings by calling the file “appsettings.{EnvironmentName}.json”. The environment specific settings override those within the main settings file. This allows you to have different connection string when working locally and when in production.

In this tutorial we'll show how you can configure your module to add some settings. We'll keep things simple for now, but knowing some of practices you have learnt so far you can easily extend it to suit your needs.

First let's add the settings class. Create a file called "ShopSettings.cs" in the root of the module with the following content:

using System.ComponentModel.DataAnnotations;
using Kit.Mvc;
using Kit.Settings;

namespace DemoShop.Shop;

[Settings("Shop", Bookmark = "shop-settings")]
[Placeholder("Settings_Admin_Settings", "Settings", "Admin", "DemoShop.Shop")]
public class ShopSettings {
    [Required]
    public int PageSize { get; set; } = 10;
}

Note: We can specify the default values for our settings in this file.

Next we'll register the setting within the container. Open the “HostingStartup.cs” file and add the following within the “ConfigureServices” method:

services.Configure<ShopSettings>(context.Configuration.GetSection("Shop"));

Note: The key passed into the “GetSection” method must match the value passed into the “Settings” attribute in the "ShopSettings" class above. This is known as the config key.

Now we'll add a way to update the settings. Open the "AdminController.cs" and make the following modifications:

First inject IOptionsMonitor<ShopSettings> into the constructor and store in the following field (adding any missing namespaces):

private readonly ShopSettings _settings;

Note: Since the injected settings are wrapped in "IOptionsMonitor", you'll need to set the field to the “CurrentValue” property.

Now add the following region block for our settings:

#region Settings Members

[ChildActionOnly, HtmlFieldPrefix("Shop.Settings")]
public IActionResult Settings() {
    return PartialView(_settings);
}

#endregion

Note: We don't have to add a permission as it uses a child action. Also the prefix must match the config key you used above.

Next we need to add the view for our Settings child action method. Create the following file called "Settings.cshtml" in the "Views/Admin" folder:

@model DemoShop.Shop.ShopSettings
<div id="shop-settings" class="card shadow">
    <div class="card-header"><h2>@Text["Shop Settings"]</h2></div>
    <div class="card-body">
        <div class="form-group">
            <label asp-for="PageSize" class="form-label"></label>
            <editor for="PageSize" />
        </div>
    </div>
</div>

All that's left to do is to use our setting. Open the "HomeController.cs" file and similarly to what we did above, inject IOptionsMonitor<ShopSettings> within the constructor and store in the following field (adding any missing namespaces):

private readonly ShopSettings _settings;

Now we just need to replace the "Index" action method with the following:

[HttpGet]
public async Task<IActionResult> Index(int page = 1) {
    return View((await _shopService.GetProductsAsync(page, _settings.PageSize)).Convert(p => new ProductViewModel(p)));
}

Note: We have changed the number of products to display to now feed in the page size from our settings.

Finally navigate to the settings page to make sure everything is working as expected.

Widgets »