ASP.NET MVC: Читаем настройки сайта из своей секции файла конфигурации web.config
Постановка задачи
Требуется создать свою секцию настроек в конфигурационном файле web.config, со структурой более "продвинутой" чем appSettings (то есть нечто большее, чем просто Dictionary). А так же надо реализовать механизм считывания и обновления данных в этой секции.
Как сохранить настройки или выбор стратегии
Снова напомню, что есть серия статей "История одного проекта" (далее ИОП), которая посвящена разработке сайта “музей юмора”. И поэтому, давайте снова поговорим про этот проект, как можно расширить возможности по администрированию этого сайта. Предположим, что лента экспонатов, должна хранить записи за какой-то определенный срок. Например, за одну неделю, то есть семь дней. А если я захочу изменить срок, например на 14 дней? А если я захочу вообще временно отключить удаление записей? А если я хочу временно запретить публикацию экспонатов на ленте через IE-ускоритель? А если... Слишком много "а если"... Надо просто эти параметры где-то хранить с возможностью управления ими непосредственно со страниц сайта. Один из вариантов - файл конфигурации web.config, можно также хранить в базе данных, или, например, в текстовом файле, или сделать другой сайт, на котором сделать web-сервис, который сможет "выдать" всем моим сайта настройки для каждого или общие для всех. Или вообще, всё выложить в облако Azure и платить некоторую сумму в Microsoft... Всё ограничено лишь вашей фантазией. Мы будем говорить про первый вариант – сохранение настроек сайта в файле конфигурации.
Итак, хранение настроек в web.config тоже можно реализовать как минимум двумя способами. Читать/писать данные в файле конфигурации можно:
- Из секции appSettings. ASP.NET предоставляет программистам в своё распоряжение самый простой вариант. Информация в этой секции хранится по принципу Dictionary (ключ = значение).
- Из собственной секции файла конфигурации. ASP.NET также предоставляет такую возможность. Структура данных в этом случае может быть сколь угодно сложной (комплексные типы), более того, вы можете гарантировать значения по умолчанию для своих параметров и даже валидацию ввода при изменении свойств, что является неоспоримым плюсом для этого способа.
Возьмем второй вариант. Мне хочется показать пример посложнее, да и структура у меня будет развиваться и совершенствоваться, а потому очень не хочется осознать в какой-то момент, что надо переписывать половину приложения, чтобы реализовать возможность читать/писать данные и настройки в своей секции конфигурации, а не из appSettings.
Начнем с простого. Пусть на данный момент мне требуется такая ветка в файле конфигурации:
1: <SiteSettingsGroup>
2: <SiteSettings>
3: <PagerSize>
4: <EntityName="Logs"Size="20"/>
5: <EntityName="Exhibit"Size="10"/>
6: <EntityName="Lenta"Size="15"/>
7: </PagerSize>
8: <LentaDeleteAfterDays="17"AllowPostFromShare="false"/>
9: </SiteSettings>
10: </SiteSettingsGroup>
Если описать вкратце, то SiteSettingsGroup – название группы. SiteSettings – это та самая секция, которую мы будем создавать. PagerSize – это коллекция с настройками размера страницы при отображении в пейджере для определенного типа сущности. Lenta – это дополнительный раздел настроек для ленты анекдотов, а значения атрибутов, итак понятны.
Немного специальных классов
Создадим несколько классов. Для начала – главный класс SiteSettings (также называется и файл .cs). Чтобы все получилось, нужно для начала добавить namespace:
using System.Configuration;
Для начала создадим первый “кирпичик” выбранной структуры – класс LentaElement из указанной выше конфигурации:
1: publicclass LentaElement : ConfigurationElement {
2:
3: [ConfigurationProperty("DeleteAfterDays", DefaultValue = 7, IsRequired = true)]
4: [IntegerValidator(MinValue = 3, MaxValue = 30, ExcludeRange = false)]
5: publicint DeleteAfterDays {
6: get {
7: return (int)this["DeleteAfterDays"];
8: }
9: set {
10: this["DeleteAfterDays"] = value;
11: }
12: }
13:
14: [ConfigurationProperty("AllowPostFromShare", DefaultValue = true, IsRequired = true)]
15: publicbool AllowPostFromShare {
16: get {
17: return (bool)this["AllowPostFromShare"];
18: }
19: set {
20: this["AllowPostFromShare"] = value;
21: }
22: }
23: }
Обратите внимание на то, что класс унаследован от ConfigurationElement. Это один из основных базовых классов, которые используются в web.config для разделов. Дальше будет понятнее.
Далее надо бы создать главный раздел для моей секции и уже использовать LentaElement как свойство. Класс я назову SiteSettings:
1: publicclass SiteSettings : ConfigurationSection {
3: [ConfigurationProperty("Lenta", IsRequired = true)]
4: public LentaElement Lenta {
6: return (LentaElement)this["Lenta"];
9: this["Lenta"] = value;
Между делом или Config-помощник
Для того, чтобы “достучаться” до любого значения любого параметра моей конфигурации, давайте прямо сейчас создадим специальный класс-помощник. Я буду его использовать чтобы протестировать работоспособность конфигурации:
1: publicclass Config {
2:
3: /// <summary>
4: /// скроем конструктор от любопытных программеров
5: /// </summary>
6: internal Config() { }
7:
8: /// <summary>
9: /// наименование раздела конфигурации
10: /// </summary>
11: privateconststring CONFIGGROUPNAME = "SiteSettingsGroup/";
12:
13: /// <summary>
14: /// наименование секции
15: /// </summary>
16: privateconststring CONFIGSECTIONNAME = "SiteSettings";
17:
18: /// <summary>
19: /// Чтение раздела конфигурации целиком
20: /// </summary>
21: /// <returns></returns>
22: internalstatic SiteSettings Get() {
23: var config = (SiteSettings)ConfigurationManager
.GetSection(String.Concat(CONFIGGROUPNAME, CONFIGSECTIONNAME));
24: return config;
25: }
26: }
А теперь пришло время попробовать что получилось. Попробуем прочитать информацию из конфигурации. Я предварительно в файле web.config пока убрал (закомментировал) из своей конфигурации секцию PagerSize. Потому что она еще не реализована, а значить приложение даже не будет пытаться запуститься, а просто вывалится с ошибкой.
В головном контролере в методе Index, я для проверки вставил пару строк, чтобы проверить что конфигурация читается, запустил и…
Отлично! Как раз то, что я и указал в своей конфигурации. Дальше - больше. Я добавил еще несколько классов. Это самое интересное. В раздел SiteSettings я добавил определение класса PagerSizeCollection. Чтобы можно было работать с коллекцией настроек. Далее определил класс PageSizeItemsElement, который и представляет собой одну из строчек в списке PagerSize… Наверное, всё-таки имеет смысл показать весь файл SiteSettings целиком:
1: publicclass SiteSettings : ConfigurationSection
2: {
3:
4: [ConfigurationProperty("PagerSize")]
5: public PagerSizeCollection PagerSize
6: {
7: get
8: {
9: return ((PagerSizeCollection)base["PagerSize"]);
10: }
11: }
12:
13: [ConfigurationProperty("Lenta", IsRequired = true)]
14: public LentaElement Lenta
15: {
16: get
17: {
18: return (LentaElement)this["Lenta"];
19: }
20: set
21: {
22: this["Lenta"] = value;
23: }
24: }
25: }
26:
27: [ConfigurationCollection(typeof(PageSizeItemsElement), AddItemName = "Entity")]
28: publicclass PagerSizeCollection : ConfigurationElementCollection
29: {
30:
31: public PageSizeItemsElement this[int index]
32: {
33: get { return (PageSizeItemsElement)BaseGet(index); }
34: }
35:
36: protectedoverride ConfigurationElement CreateNewElement()
37: {
38: returnnew PageSizeItemsElement();
39: }
40:
41: protectedoverrideobject GetElementKey(ConfigurationElement element)
42: {
43: return ((PageSizeItemsElement)element).Name;
44: }
45: }
46:
47: publicclass PageSizeItemsElement : ConfigurationElement
48: {
49:
50: [ConfigurationProperty("Size", DefaultValue = 20, IsRequired = true)]
51: [IntegerValidator(MinValue = 5, MaxValue = 100, ExcludeRange = false)]
52: publicint Size
53: {
54: get
55: {
56: return (int)this["Size"];
57: }
58: set
59: {
60: this["Size"] = value;
61: }
62: }
63:
64: [ConfigurationProperty("Name", DefaultValue = "EntityName", IsRequired = true)]
65: [StringValidator(MinLength = 3, MaxLength = 50,
InvalidCharacters = " ~!@#$%^&*()[]{}/;'\"|\\")]
66: public String Name
67: {
68: get
69: {
70: return (String)this["Name"];
71: }
72: set
73: {
74: this["Name"] = value;
75: }
76: }
77: }
78:
79: public class LentaElement : ConfigurationElement
80: {
81:
82: [ConfigurationProperty("DeleteAfterDays", DefaultValue = 7, IsRequired = true)]
83: [IntegerValidator(MinValue = 3, MaxValue = 30, ExcludeRange = false)]
84: public int DeleteAfterDays
85: {
86: get
87: {
88: return (int)this["DeleteAfterDays"];
89: }
90: set
91: {
92: this["DeleteAfterDays"] = value;
93: }
94: }
95:
96: [ConfigurationProperty("AllowPostFromShare", DefaultValue = true, IsRequired = true)]
97: public bool AllowPostFromShare
98: {
99: get
100: {
101: return (bool)this["AllowPostFromShare"];
102: }
103: set
104: {
105: this["AllowPostFromShare"] = value;
106: }
107: }
108: }
Чтобы проверить работоспособность проделываю такую же операцию как и в прошлый раз:
Всё работает. Теперь осталось в подключить настройки к системе, то есть начать использовать их. Читается всё замечательно. Попробуем сохранить?
Заключение
В следующей статье я создам форму редактирования настроек (скорее всего это будет knockout.js, то есть значит AJAX).
Подробнее: http://feedproxy.google.com/~r/blogmusor/~3/rSNupmGLoRo/95


Поделиться статьей:
Акция: Закажи любой сайт до окончания акции и получи скидку + подбор семантического ядра + поисковую оптимизацию сайта Это позволит Вам получать еще больше трафика и соответственно клиентов из Интернета!
До конца акции осталось
0
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
|
Узнайте подробности акции у менеджеров компании по телефонам: 8-924-200-7194 г.Хабаровск 8-800-550-9899 Бесплатно по России (с 2:30 до 11:30 по Мск) |
Новые статьи и публикации
- 2021-02-24 » Как попасть в Clubhouse и что там делать: гид по новой соцсети
- 2021-02-24 » ТОП-10 онлайн-консультантов для сайта
- 2021-02-16 » UX-копирайтинг: как небольшие тексты существенно повышают продажи
- 2021-02-08 » Яндекс.Кью: особенности сервиса и его польза для бизнеса
- 2021-02-01 » Покупательское поведение пользователей: как оно изменилось за последнее время?
- 2021-01-22 » PHP и регулярные выражения: азы для новичков
- 2021-01-22 » Факторы ранжирования-2021
- 2021-01-19 » Вопросы юзабилити: на что обратить внимание в 2021 году?
- 2021-01-12 » Алгоритм YATI: новая разработка Яндекса
- 2020-12-29 » DdoS-атаки: суть и способы защиты от них
- 2020-12-21 » Оплата за конверсии в Яндекс.Директе: в чём выгода и как проходит подключение?
- 2020-12-14 » Предновогодняя суета: как привлечь клиентов и активизировать продажи?
- 2020-12-03 » Ведение блога: на своём сайте или на специальной платформе?
- 2020-11-30 » Виджеты для веб-сайтов: влияние кнопок на продажи
- 2020-11-30 » CRM: что это и как помогает бизнесу?
- 2020-11-13 » Тепловые карты сайта: особенности и возможности для продвижения
- 2020-11-11 » Яндекс.Клиенты: всё о новых возможностях георекламы
- 2020-10-27 » Описания товаров для интернет-магазинов: секреты успешных продаж
- 2020-10-27 » Увеличиваем мобильный трафик: 10 способов привлечь новых клиентов
- 2020-10-14 » Определение CMS сайта: как это сделать?
- 2020-10-13 » Сайты-агрегаторы: сотрудничать или бороться за ТОП?
- 2020-10-05 » Интернет-магазин в Instagram: как его открыть?
- 2020-09-28 » Интернет-тролли: как с ними бороться и не подмочить репутацию?
- 2020-09-17 » Bing: обновление для веб-мастеров
- 2020-09-15 » Подключение платформы Яндекс.Диалоги на веб-сайт
- 2020-09-07 » Яндекс.Вордстат: как это работает?
- 2020-08-27 » Настройка аудиорекламы в социальных сетях: как её выполнить?
- 2020-08-21 » Текст для карточки товара: как сделать идеальное описание?
- 2020-08-17 » Сайты-визитки: какими они должны быть?
- 2020-08-10 » Оценка страниц Google: как это работает?
Предоставляем полный комплекс услуг по созданию, обслуживанию и продвижению сайтов по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.