Skip to main content

ConfigurationIgnoreAttribute in .NET 11

4/26/2026
2 minute read

Microsoft.Extensions.Configuration has had ConfigurationKeyNameAttribute since .NET 6 which it lets you rename the key a property maps to. But there was never an official way to say "don't bind this property at all." That gap is finally closed in .NET 11 with ConfigurationIgnoreAttribute.

The Problem#

Let's say you have an options class that looks roughly like this:

csharp
public class CsvIngestionOptions
{
    // Computed after load — should NOT come from configuration
    public CsvFormatOptions DefaultFormat { get; set; }

    // The raw section we bind and process ourselves
    public IConfigurationSection? DefaultFormatSection { get; set; }

    internal void OnConfigurationLoaded()
    {
        DefaultFormat = new CsvFormatOptions();
        DefaultFormatSection?.Bind(DefaultFormat);
        DefaultFormat.EnsureEncodingDefined();
    }
}

DefaultFormat is derived from DefaultFormatSection after some post-processing. It should never be populated directly by the binder. But because it has a public getter and setter, the configuration system happily tries to bind it.

The only workaround before .NET 11 was to abuse ConfigurationKeyNameAttribute with an intentionally garbage key:

csharp
// The hacky way
[ConfigurationKeyName("__ignored_" + nameof(DefaultFormat))]
public CsvFormatOptions DefaultFormat { get; set; }

That's fragile, misleading, and creates a weird surface in your configuration schema. Not great.

The Fix: ConfigurationIgnoreAttribute#

.NET 11 adds a dedicated attribute in Microsoft.Extensions.Configuration:

csharp
namespace Microsoft.Extensions.Configuration;

[AttributeUsage(AttributeTargets.Property)]
public sealed class ConfigurationIgnoreAttribute : Attribute { }

Easy peasy. Just add the property now to the property in question that should not be bound:

csharp
public class CsvIngestionOptions
{
    [ConfigurationIgnore]
    public CsvFormatOptions DefaultFormat { get; set; }

    [ConfigurationKeyName(nameof(DefaultFormat))]
    public IConfigurationSection? DefaultFormatSection { get; set; }

    internal void OnConfigurationLoaded()
    {
        DefaultFormat = new CsvFormatOptions();
        DefaultFormatSection?.Bind(DefaultFormat);
        DefaultFormat.EnsureEncodingDefined();
    }
}

Another Common Scenario#

Post-processing is the most obvious use case, but not the only one. A parsed representation of a raw value is another classic:

csharp
public class FeatureFlags
{
    public string RawFlags { get; set; } = string.Empty;

    [ConfigurationIgnore]
    public IReadOnlyDictionary<string, bool> ParsedFlags { get; set; }
        = new Dictionary<string, bool>();
}

Can't I Just Use [JsonIgnore]?#

Nope and this is the catch. System.Text.Json.Serialization.JsonIgnoreAttribute has no effect on the configuration binder.

GitHub#

The issue is described here: https://github.com/dotnet/runtime/issues/125111

An error has occurred. This application may no longer respond until reloaded.Reload x