Статьи

Как добавить пользовательские параметры конфигурации для приложения (ASP) .NET

С момента своего выпуска приложения и компоненты ASP.NET обращались к файлу web.config, чтобы загрузить любые параметры, необходимые для работы. Однако добавление пользовательских настроек для добавления гибкости и надежности в приложение или компонент не так просто, как хотелось бы большинству. В этой статье вы узнаете, как написать необходимые классы для обработки элементов конфигурации XML и использовать параметры, содержащиеся в вашем коде.

Переизданный учебник

Каждые несколько недель мы пересматриваем некоторые из любимых постов нашего читателя на протяжении всей истории сайта. Этот учебник был впервые опубликован в ноябре 2012 года.

.NET Framework предоставляет широкий набор параметров, которые можно настроить в файле web.config для изменения поведения одного или нескольких встроенных компонентов в приложении. Для некоторых разработчиков достаточно придерживаться только настроек, предоставляемых .NET Framework. Но многие другие разработчики считают, что им необходимо управлять более широким набором параметров — либо для компонентов (написанных ими самими или сторонними разработчиками), либо просто для набора значений, которые они используют в своем приложении.

Файл web.config позволяет вам устанавливать пользовательские настройки с помощью элемента <appSettings />, но он не допускает ничего, кроме простых пар ключ / значение. Следующий XML-элемент является примером настройки, содержащейся в <appSettings />:

1
<add key=»myKey» value=»myValue»/>

Настройки «ключ / значение», безусловно, могут быть полезны во многих случаях, но настройки <appSettings /> просто недостаточно гибки для надежных или сложных компонентов или настроек.

К счастью, Microsoft позволяет разработчикам писать классы, которые добавляют программный доступ к настраиваемым параметрам конфигурации, содержащимся в web.config.


Настройки в файле web.config подразделяются на разделы конфигурации. Например, параметры, содержащиеся в разделе <system.web/> к параметрам ASP.NET для вашего приложения. Вы можете изменить схему аутентификации вашего приложения, а также добавить или удалить обработчики HTTP для выполнения определенных функций для определенных типов файлов. Раздел <system.webServer /> позволяет вам управлять многими настройками IIS7, не имея прямого доступа к IIS7.

Раздел конфигурации необходим для всех параметров, не содержащихся в элементе <appSettings />. Поэтому неплохо было бы спроектировать структуру XML ваших настроек конфигурации перед написанием любого кода.

Конфигурация, используемая в качестве примера в этом руководстве, предназначена для компонента, который извлекает каналы RSS или Atom. Он не выполняет никакого анализа, поскольку это выходит за рамки данного руководства. Вместо жесткого кодирования списка каналов для извлечения, компонент ищет свою конфигурацию, содержащую имена и URL-адреса каналов для извлечения. Компонент называется FeedRetriever, и желаемая XML-структура его конфигурации выглядит следующим образом:

1
2
3
4
5
6
7
<feedRetriever>
    <feeds>
        <add name=»Nettuts+» url=»https://feeds.feedburner.com/nettuts» cache=»false»/>
        <add name=»Jeremy McPeak» url=»http://www.wdonline.com/feeds/blog/rss/» />
        <add name=»Nicholas C. Zakas» url=»http://feeds.nczonline.net/blog/» />
    </feeds>
</feedRetriever>

Элемент <feedRetriever /> определяется разделом конфигурации. Как правило, раздел конфигурации должен содержать имя компонента, для которого он предназначен. Только дочерний элемент <feedRetriever /> элементов является элементом <feeds />. Думайте об этом элементе как о коллекции каналов, потому что он содержит несколько элементов <add /> (подумайте о методе Add (), который есть у большинства объектов коллекции). Выбор использования элемента с именем «add» на первый взгляд может показаться странным, но элемент <add /> используется в большинстве встроенных разделов конфигурации. Таким образом, использование его здесь просто следует методам проектирования, предложенным Microsoft.

Эти элементы <add /> используют атрибуты name, url и cache, чтобы установить определенные настройки для каждого канала. Естественно, атрибуты name и url обязательны, а атрибут cache — нет, и по умолчанию должен иметь значение true.

Вышеуказанная конфигурация проста. Элемент <feedRetriever /> можно изменить, чтобы он содержал другого дочернего элемента с именем <globalSettings />, чтобы он содержал настройки, которые будут применяться ко всем каналам. Элементы <add /> могут также использовать дополнительные атрибуты, такие как cacheTime и requestFrequency, чтобы контролировать продолжительность кэширования канала и частоту его запроса с удаленного хоста. Единственным ограничением расширяемости и конфигурируемости является ваше воображение.


После проектирования структуры XML следующим шагом является написание обработчика конфигурации для обработки параметров, определенных в XML. Обработчик — это прежде всего класс, который наследуется от System.Configuration.ConfigurationSection , но он также включает использование других классов, таких как классы, производные от System.Configuration.ConfigurationElement и System.Configuration.ConfigurationElementCollection .

Классы на основе ConfigurationElement представляют отдельные элементы; это строительный блок раздела конфигурации. Типы, производные от ConfigurationElementCollection, просто представляют элементы, которые содержат более одного типа элемента. Из конфигурации, указанной выше, элемент <feeds /> представлен классом, производным от ConfigurationElementCollection, а элементы <add /> представлены классом на основе ConfigurationElement.


Вы начнете с элемента <add />, представив его классом с именем FeedElement (производным от ConfigurationElement). Этот класс и будущие связанные с конфигурацией классы находятся в пространстве имен FeedRetriever.Configuration.

Каждый объект ConfigurationElement функционирует как индексатор для своей внутренней коллекции значений свойств. Именно эта внутренняя коллекция вместе с атрибутами .NET позволяет сопоставлять атрибуты элемента <add /> со свойствами класса FeedElement.

Следующий код является полным кодом для класса FeedElement:

Класс ConfigurationElement служит индексатором для базовой коллекции свойств конфигурации (отсюда обозначение индексатора этого [keyValue]). Используя ключевое слово this и получая доступ к базовому свойству с помощью строкового ключа, вы можете получить и установить значение свойства без необходимости в закрытом поле для хранения этих данных. Базовая коллекция свойств хранит данные как тип Object; следовательно, вы должны привести значение к соответствующему типу, если хотите что-то с ним сделать.

Свойства, которые представляют атрибуты XML, украшены атрибутами ConfigurationPropertyAttribute . Первым параметром атрибута ConfigurationPropertyAttribute является имя атрибута XML, найденного в элементе <add />. После первого параметра указывается набор любого количества именованных параметров. Следующий список представляет собой полный список возможных параметров:

  • DefaultValue — получает или задает значение по умолчанию для оформленного свойства. Этот параметр
    не требуется.
  • IsDefaultCollection — получает или устанавливает логическое значение, указывающее, является ли свойство
    является коллекцией свойств по умолчанию для оформленного свойства. Этот параметр
    не требуется, и по умолчанию установлено значение false.
  • IsKey — получает или задает логическое значение, указывающее, является ли это свойство ключевым свойством
    для оформленного элемента собственности. Этот параметр не является обязательным, и его значение по умолчанию
    значение ложно.
  • IsRequired — получает или устанавливает логическое значение, указывающее, является ли декорированный элемент
    собственность обязательна. Этот параметр не является обязательным, и его значение по умолчанию — false.

Значение по умолчанию «http: // localhost» для свойства Url не является ошибкой. .NET Framework также предоставляет вам возможность украшать свойства с помощью атрибутов валидатора, таких как RegexStringValidatorAttribute, украшающий свойство Url. Этот валидатор принимает значение свойства Url и проверяет его на соответствие регулярному выражению, предоставленному атрибуту; однако он также проверяет свойство Url, прежде чем он содержит данные из элемента XML. Значением по умолчанию свойства Url является пустая строка при первом создании объекта FeedElement. Пустая строка не проверяется по предоставленному регулярному выражению, поэтому валидатор выдает исключение ArgumentException до того, как из файла XML будут загружены какие-либо данные.

Есть два возможных решения этой проблемы. Первый подход изменяет регулярное выражение, чтобы разрешить пустые строки. Второй подход назначает значение по умолчанию для свойства. Это не имеет значения в данном конкретном случае. Даже со значением по умолчанию атрибут url по-прежнему является обязательным атрибутом в элементе <add /> — приложение выдает исключение ConfigurationErrorsException, если элемент <add /> не имеет атрибута url.

Есть несколько других атрибутов валидатора в пространстве имен System.Configuration для проверки данных, назначенных свойствам, и атрибутов XML, с которыми они сопоставляются. Ниже перечислены все атрибуты валидатора в пространстве имен System.Configuration:

  • CallbackValidatorAttribute — обеспечивает связь между объектом CallbackValidator и кодом для проверки — позволяет
    динамическая проверка значения конфигурации.
  • IntegerValidatorAttributeпроверяет использование объекта IntegerValidator, чтобы определить, находится ли значение конфигурации в пределах или за пределами определенного диапазона.
  • LongValidatorAttributeпроверяет использование объекта LongValidator, чтобы определить, находится ли значение конфигурации в пределах или за пределами определенного диапазона.
  • PositiveTimeSpanValidatorAttribute — проверяет использование объекта PositiveTimeSpanValidator для положительных значений конфигурации TimeSpan.
  • RegexStringValidatorAttributeпроверяет использование объекта RegexStringValidator, чтобы определить, соответствует ли значение конфигурации регулярному выражению.
  • StringValidatorAttributeпроверяет использование объекта StringValidator, чтобы убедиться, что значение конфигурации соответствует определенным критериям, таким как длина строки и недопустимые символы.
  • SubclassTypeValidatorAttribute — проверяет использование объекта SubclassTypeValidator, чтобы определить, является ли значение конфигурации определенного типа.
  • TimeSpanValidatorAttribute — проверяет использование объекта TimeSpanValidator, чтобы определить, находится ли значение конфигурации в пределах или за пределами определенного диапазона.

За исключением CallbackValidatorAttribute, вам не нужно создавать соответствующие объекты валидатора для использования вместе с атрибутами валидатора. Среда выполнения .NET создает для вас соответствующие объекты валидатора, а атрибуты содержат необходимые параметры для настройки объектов валидатора.

Этот небольшой кусочек кода — это все, что требуется для программного представления отдельных элементов <add />. Следующим шагом является написание класса, который представляет элемент <feeds />.


XML-представление элемента <feeds /> является представлением коллекции элементов feed. Аналогично, программное представление элемента <feeds /> является коллекцией объектов FeedElement. Этот класс, называемый FeedElementCollection, является производным от абстрактного класса ConfigurationElementCollection.

Класс ConfigurationElementCollection содержит несколько членов, но только два помечены как абстрактные. Таким образом, простейшая реализация ConfigurationElementCollection имеет два метода:

  • CreateNewElement () — создает новый объект ConfigurationElement (в этом FeedElement
    кейс).
  • GetElementKey () — получает ключ элемента для указанного элемента конфигурации (
    Имя свойства объектов FeedElement в этом случае).

Имея это в виду, просмотрите полный код для класса FeedElementCollection ниже:

ConfigurationCollectionAttribute украшает этот класс коллекции. Первым параметром атрибута является объект Type — тип элементов, содержащихся в коллекции. В данном случае это тип FeedElement. После параметра типа есть несколько именованных параметров, которые вы можете передать атрибуту. Они перечислены ниже:

  • AddItemName — устанавливает имя элемента конфигурации <add />. Например,
    установка этого параметра в качестве «подачи» потребует элементов <add /> в
    Конфигурация будет изменена на <feed />.
  • ClearItemsName — устанавливает имя элемента конфигурации <clear /> (используется
    очистить все предметы из коллекции).
  • RemoveItemName — устанавливает имя для элемента конфигурации <remove /> (используется
    удалить элемент из коллекции).

Оставив эти именованные параметры пустыми, по умолчанию они имеют значение <add />, <clear />, <remove />.


Последний класс, называемый FeedRetrieverSection, является производным от ConfigurationSection и представляет элемент <feedRetriever />. Это самый простой класс классов конфигурации, поскольку единственное требование, которому он должен соответствовать, — это обеспечить программный доступ к элементу <feeds /> (FeedElementCollection).

Это одно свойство, типа FeedElementCollection и называемое Feeds, украшено ConfigurationPropertyAttribute — сопоставление его с элементом <feeds />.


Закончив обработчик конфигурации, вы можете добавить соответствующие элементы в web.config. Раздел <feedRetriever /> может находиться в любом месте файла, если он является прямым потомком корневого элемента (элемента <configuration />). Размещение его в другом разделе конфигурации приводит к ошибке.

Следующим шагом является добавление дочернего элемента <section /> в <configSections />. Элемент <section /> имеет два интересующих атрибута:

  • name — Имя элемента секции конфигурации. В этом случае имя — feedRetriever.
  • type — Полное имя класса, связанного с разделом, и, если необходимо,
    имя сборки, в которой находится класс. В этом случае полное имя
    является FeedRetriever.Configuration.FeedRetrieverSection. Если он находится в отдельном
    сборка, атрибут типа будет иметь значение «FeedRetriever.Configuration.FeedRetrieverSection,
    <assemblyName> «, где <assemblyName> — это имя сборки
    без угловых скобок.

Следующий элемент <section /> — это то, что вы добавляете в файл web.config в <configSections />, когда классы конфигурации не находятся в отдельной сборке (как в случае загрузки кода):

1
<section name=»feedRetriever» type=»FeedRetriever.Configuration.FeedRetrieverSection»/>

Теперь ваше приложение правильно настроено на использование классов FeedRetrieverSection, FeedElementCollection и FeedElement, чтобы предоставить вам программный доступ к пользовательским настройкам, содержащимся в разделе конфигурации <feedRetriever /> в файле web.config. Итак, как вы получаете доступ к этим настройкам из своего кода?


Пространство имен System.Configuration содержит статический класс с именем ConfigurationManager. Если вы используете раздел <connectionStrings /> для размещения строк подключения, вы, по крайней мере, знакомы с ConfigurationManager. У него есть метод GetSection (), который принимает строку, содержащую имя раздела конфигурации для извлечения. Следующий код демонстрирует это (предположим, что использование System.Configuration находится в верхней части файла кода):

Метод GetSection () возвращает значение типа Object, поэтому оно должно быть приведено к тому типу, который является обработчиком для этого раздела. Этот код извлекает раздел с именем feedRetriever и возвращает результат как FeedRetrieverSection. Когда у вас есть объект, вы можете начать доступ к данным конфигурации программно.

Чтобы дать вам представление о том, как можно использовать параметры конфигурации в вашем компоненте или приложении, следующий код является базовой реализацией компонента FeedRetriever.

Сначала объявляется статическая переменная _Config типа FeedRetreiverSection, которой присваивается значение путем вызова ConfigurationManager.GetSection (). Создание статической переменной — это выбор дизайна. Таким образом, все члены класса, как экземпляры, так и статические, получат доступ к настройкам конфигурации, не делая многократных вызовов GetSection ().

Получив обработчик раздела с помощью GetSection (), вы получаете полный доступ к объектам, созданным из ваших классов-обработчиков. Первая строка GetFeeds () — это цикл для каждого цикла, который проходит по всем объектам FeedElement, содержащимся в объекте FeedElementCollection, возвращаемом свойством Feeds. Это дает вам прямой доступ к этим объектам FeedElement, упрощая доступ к имени каждого канала, URL-адресу и настройкам кэша.

Во время каждой итерации цикла метод делает запрос, используя свойство Url объекта FeedElement. Если запрос приводит к успеху, данные фида извлекаются и сохраняются в переменной feedData. Затем код проверяет свойство Cache объекта FeedElement, чтобы определить, следует ли кэшировать канал. Кэширование канала включает создание имени файла с использованием свойства Name объекта FeedElement и текущей даты и времени. Затем объект StreamWriter создает файл и записывает в него данные канала.

Как вы можете видеть, использование классов обработчиков раздела конфигурации является ключом к получению и использованию пользовательских настроек, находящихся в web.config. Это, безусловно, требует от вас больше времени и усилий, но, безусловно, значительно упрощает настройку вашего приложения или компонента для вас и других разработчиков.



CodeCanyon

Знаете ли вы, что у нас есть категория .NET на CodeCanyon . Если вы опытный разработчик .NET, почему бы не продавать свои скрипты / компоненты / элементы управления в качестве автора и зарабатывать 40-70% от каждой продажи ?

  • Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке.