DEV Community

Cover image for ASP.NET Core startup validation part 4
Karen Payne
Karen Payne

Posted on

ASP.NET Core startup validation part 4

Introduction

Learn how to use a class that implements IValidateOptions to validate that sections exist with the required keys in the appsettings.json file.

Source code

Source code requires Microsoft Visual Studion 2022 or higher.

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Microsoft.EntityFrameworkCore.Database.Command": "Information",
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Helpdesk": {
    "Phone": "123-456-7890",
    "Email": "helpdesk@example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

In the file, we want to validate that both Logging and HelpDesk are validated.

Required classes

💡 properties must be nullable for validation code to work.

public class LogLevelSettings
{
    public string? Default { get; set; } = string.Empty;

    [ConfigurationKeyName("Microsoft.AspNetCore")]
    public string? MicrosoftAspNetCore { get; set; } = string.Empty;

    [ConfigurationKeyName("Microsoft.EntityFrameworkCore.Database.Command")]
    public string? MicrosoftEntityFrameworkCoreDatabaseCommand { get; set; } = string.Empty;
}

public class HelpDesk
{
    public string? Phone { get; set; }
    public string? Email { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

_Layout.cshtml

Note that the following lines are needed for displaying HelpDesk values

@using GetSettingFromAppSettings.Models
@using Microsoft.Extensions.Options
@inject IOptions<HelpDesk> HelpdeskOptions
Enter fullscreen mode Exit fullscreen mode

Validation class

Responsible for the validation of a section in the above appsettings file.

  • The Validate method checks:
    • For required sections
    • Calls ValidateValue to check that the required keys exist

If errors list is not empty indicates failure.

public sealed class LoggingSettingsValidation(IConfiguration configuration) : 
    IValidateOptions<LoggingSettings>
{

    public ValidateOptionsResult Validate(string? name, LoggingSettings options)
    {
        List<string> errors = [];

        var loggingSection = configuration.GetSection("Logging");
        if (!loggingSection.Exists())
        {
            errors.Add("Configuration section 'Logging' is missing.");
            return ValidateOptionsResult.Fail(errors);
        }

        var logLevelSection = configuration.GetSection("Logging:LogLevel");
        if (!logLevelSection.Exists())
        {
            errors.Add("Configuration section 'Logging:LogLevel' is missing.");
            return ValidateOptionsResult.Fail(errors);
        }

        ValidateValue("Logging:LogLevel:Default", errors);
        ValidateValue("Logging:LogLevel:Microsoft.AspNetCore", errors);
        ValidateValue("Logging:LogLevel:Microsoft.EntityFrameworkCore.Database.Command", errors);

        return errors.Count > 0
            ? ValidateOptionsResult.Fail(errors)
            : ValidateOptionsResult.Success;
    }


    private void ValidateValue(string key, List<string> errors)
    {
        var value = configuration[key];

        if (string.IsNullOrWhiteSpace(value))
        {
            errors.Add($"Configuration value '{key}' is missing or empty.");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Program.cs code

The following code is used to invoke LoggingSettingsValidation assertions.

builder.Services
    .AddOptions<LoggingSettings>()
    .Bind(builder.Configuration.GetSection("Logging"))
    .ValidateOnStart();

builder.Services.AddSingleton<IValidateOptions<LoggingSettings>, LoggingSettingsValidation>();
Enter fullscreen mode Exit fullscreen mode

See also

Summary

Some developers may think the code presented is great, while others might consider the validation presented overkill. It depends on how the code is tested and if there are steps to manually check that sections and keys exist. To keep a web application running correctly, test and use the provided code.

Optional

If more than one web application requires appsetting validation, consider moving the code to a class project compiled to a local NuGet package for consistency and maintenance.

Top comments (0)