TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3182 1.93K
День 2655. #ЧтоНовенького
Атрибут ConfigurationIgnore в .NET 11
В Microsoft.Extensions.Configuration атрибут ConfigurationKeyNameAttribute существует с .NET 6 и позволяет переименовывать ключ, к которому привязано свойство. Но официального способа указать «не привязывать это свойство вообще» никогда не было. Этот пробел наконец-то устранён в .NET 11 с помощью ConfigurationIgnoreAttribute.

Проблема
Допустим, у вас есть класс параметров, который выглядит примерно так:
public class CsvIngestionOptions
{
// Вычисляется после загрузки – НЕ должен идти из конфигурации
public CsvFormatOptions DefaultFormat { get; set; }

// Раздел конфигурации, который мы привязываем и обрабатываем
public IConfigurationSection? DefaultFormatSection { get; set; }

// Вызывается после загрузки конфигурации, чтобы применить постобработку и значения по умолчанию
internal void OnConfigurationLoaded()
{
DefaultFormat = new CsvFormatOptions();
DefaultFormatSection?.Bind(DefaultFormat);
DefaultFormat.EnsureEncodingDefined();
}
}

DefaultFormat извлекается из DefaultFormatSection после некоторой постобработки. Его никогда не следует заполнять напрямую связывателем. Но поскольку у него есть публичные геттер и сеттер, система конфигурации пытается его связать.

Единственным обходным путём до .NET 11 было злоупотребление ConfigurationKeyNameAttribute с намеренно некорректным ключом:
// Костыль
[ConfigurationKeyName("__ignored_" + nameof(DefaultFormat))]
public CsvFormatOptions DefaultFormat { get; set; }

Это ненадёжно, вводит в заблуждение и создаёт странный код в вашей схеме конфигурации.

Решение
.NET 11 добавляет специальный атрибут ConfigurationIgnoreAttribute в Microsoft.Extensions.Configuration. Просто добавляем атрибут к тому свойству, которое не должно быть привязано:
public class CsvIngestionOptions
{
[ConfigurationIgnore]
public CsvFormatOptions DefaultFormat { get; set; }

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


Ещё один распространённый сценарий
Постобработка — наиболее очевидный, но не единственный вариант использования. Ещё один классический пример — парсинг исходного значения:
public class FeatureFlags
{
public string RawFlags { get; set; } = string.Empty;

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


Можно ли просто использовать [JsonIgnore]?
Нет, в этом и проблема. System.Text.Json.Serialization.JsonIgnoreAttribute не влияет на связыватель конфигурации.

Замечание: начиная с .NET 9, связыватель уже пропускает свойства только для чтения (только-get/только-init при отсутствии соответствующего раздела). Предлагаемый здесь атрибут предназначен для свойств, доступных для записи, которые могут быть связаны, но не должны быть связаны.

См. также обсуждение проблемы на GitHub.

Источник:
https://steven-giesel.com/blogPost/18a61100-6074-43ac-86ae-573ad66a2c8a/configurationignoreattribute-in-net-11
  • 👍 1
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →