Блокировка разделов конфигурации
69ASP.NET --- ASP.NET Web Forms 4.5 --- Блокировка разделов конфигурации
Ранее мы объяснили, каким образом конфигурационные файлы организуются в иерархию и затем объединяются с целью создания полной конфигурации для приложения. Мы показали, как использовать атрибуты allowDefinition и allowLocation для управления тем, в каких местах разделы могут применяться. Однако мы можем пойти еще дальше и блокировать значения после их определения, чтобы предотвратить их изменение на более низких уровнях иерархии конфигурации. Эта часть конфигурации называется блокированием. Атрибуты, применяемые для блокирования, описаны в таблице ниже:
Атрибут | Описание |
---|---|
lockAllAttributesExcept | Предотвращает изменения, вносимые на более низких уровнях в иерархии конфигурации, для всех элементов, исключая указанные. Множество элементов разделяются запятыми |
lockAllElementsExcept | Предотвращает изменения, вносимые на более низких уровнях, для дочерних элементов, исключая указанные |
lockAttributes | Предотвращает изменения, вносимые на более низких уровнях, для указанных атрибутов |
lockElements | Предотвращает изменения, вносимые на более низких уровнях, для указанных дочерних элементов |
lockItem | Предотвращает изменения, вносимые на более низких уровнях, для элемента, а также для всех его атрибутов и дочерних элементов |
Атрибуты блокирования могут применяться к любому разделу конфигурации, но их нельзя использовать для групп разделов. В примере ниже демонстрируется применение атрибутов блокирования в файле Web.config:
...
<customDefaults>
<newUserDefaults city="Москва" country="Россия" language="Русский" regionCode="77"
lockAllAttributesExcept="language"/>
<colors default="GRE" lockItem="true">
<add code="GRE" value="green" name="Зеленый" />
<add code="BLU" value="blue" name="Синий" />
<add code="RED" value="red" name="Красный" />
</colors>
</customDefaults>
...
Мы применили атрибут lockAllAttributesExcept к разделу newUserDefaults и указали, что на более низких уровнях в иерархии конфигурации может изменяться только атрибут language. Поскольку мы имеем дело с файлом Web.config уровня приложения, блокировка касается элементов location и файлов Web.config уровня папок. К разделу colors применен атрибут lockItem, который предотвратит внесение изменений в атрибуты и дочерние элементы для элемента colors.
Чтобы продемонстрировать воздействие перечисленных выше атрибутов, мы модифицировали элемент location в файле Web.config, как показано в примере ниже:
...
<location path="Admin/FolderForm.aspx">
<customDefaults>
<newUserDefaults language="Французский" regionCode="2" />
<colors default="BLU">
<add code="ORA" value="orange" name="апельсиновый" />
</colors>
</customDefaults>
</location>
...
Элемент location нарушает обе блокировки. В элементе newUserDefaults определен атрибут regionCode, а внутри элемента colors присутствует дочерний элемент add. Блокировка не оценивается до тех пор, пока не будет запрошено определение элемента, к которому она применена, находящееся на более низком уровне. Это означает, что проблемы в элементе location не обнаружатся до тех пор, пока внутри веб-формы Admin\FolderForm.aspx не будут запрошены элементы newUserDefaults или colors (и даже тогда сообщается о наличии проблем блокировки в запрошенном разделе).
Одним важным следствием из способа оценки разделов конфигурации является необходимость проведения тщательного тестирования, которое даст возможность удостовериться в том, что конфигурация низкого уровня не нарушит блокировку после того, как приложение развернуто.
В примере ниже приведена модифицированная версия файла отделенного кода Admin\FolderForm.aspx.cs с обращением к обоим разделам конфигурации, к которым применены блокировки:
using System.Web.Configuration;
using System.Collections.Generic;
using System.Configuration;
namespace ConfigFiles.Admin
{
public partial class FolderForm : System.Web.UI.Page
{
public IEnumerable<string> GetConfig()
{
NewUserDefaultsSection defaults
= (NewUserDefaultsSection)WebConfigurationManager
.GetSection("customDefaults/newUserDefaults");
yield return string.Format("Значения: {0}, {1}, {2}, {3}<br><br>",
defaults.City, defaults.Country, defaults.Language, defaults.Region);
Configuration config
= WebConfigurationManager.OpenWebConfiguration(Request.Path);
UserAndPlaceSectiongroup group
= (UserAndPlaceSectiongroup)config.SectionGroups["customDefaults"];
ColorSection section = group.Colors;
Color defaultColor = section.Colors[section.Default];
yield return string.Format(
@"Цвет по умолчанию - <span style=""color:white;background:{0}"">{1}</span><br><br>",
defaultColor.Value, defaultColor.Name);
foreach (Color color in section.Colors)
yield return string.Format(
@"Цвет - <span style=""color:white;background:{0}"">{1}</span><br><br>",
color.Value, color.Name);
}
}
}
Код в примере предназначен только для демонстрации результатов нарушения блокировки, определенной в разделе конфигурации на более высоком уровне, которые можно увидеть, запустив приложение и запросив веб-форму Admin/FolderForm.aspx:

Если приложение запускается в отладчике Visual Studio, сообщение об ошибке, показанное на рисунке не отобразится, т.к. отладчик перехватит исключение и остановит выполнение кода. Нажатие клавиши <F5> приведет к возобновлению выполнения и отображению этого сообщения об ошибке.
Сообщение об ошибке, отображаемое в браузере, содержит подробные сведения о возникшей проблеме:
Сообщение об ошибке синтаксического анализатора: Атрибут 'regionCode' был заблокирован в конфигурации высшего уровня.
Мы видим подробности только одной из проблем в конфигурационном файле уровня папки, поскольку разделы конфигурации оцениваются по очереди. (И, как уже упоминалось, никаких сообщений о проблемах с разделами, обращение к которым отсутствует, выдаваться не будет.) Исправить проблемы, вызванные блокировками, довольно просто: нужно либо обновить конфигурацию низкого уровня, чтобы заблокированные элементы и атрибуты не изменялись, либо удалить блокировки.
Однако когда дело доходит до разделов конфигурации в виде коллекций, вариантов становится больше. В примере ниже приведено содержимое файла Web.config с модифицированной блокировкой:
...
<customDefaults>
<newUserDefaults city="Москва" country="Россия" language="Русский" regionCode="77"/>
<colors default="GRE" lockElements="clear,remove">
<add code="GRE" value="green" name="Зеленый" />
<add code="BLU" value="blue" name="Синий" />
<add code="RED" value="red" name="Красный" />
</colors>
</customDefaults>
...
Мы удалили атрибут lock из раздела newUserDefaults, а также изменили блокировку для раздела colors. С помощью атрибута lockElements мы запретили изменение дочерних элементов remove и clear. Это разрешает добавление новых элементов в конфигурациях более низкого уровня, но запрещает удаление существующих элементов:

Мы часто применяем такой прием, чтобы предохранить ряд ключевых значений, от которых зависит код. Он позволяет командам работать над периферийными частями приложения, добавляя все, что им необходимо.
Установив атрибут allowOverride в false, можно предотвратить переопределение контента элементов location в конфигурациях более низкого уровня. Мы предпочитаем использовать блокирование разделов конфигурации, т.к. оно обладает высокой степенью детализации. Чтобы предотвратить определение разделов в конфигурациях, специфичных для папок, следует применять атрибут allowDefinition в элементе section.