ASP.NET MVC. Конфигурационен файл Web.config. Част 2. Настройка и използване
Това е втората част от урока за конфигурационния файл Web.config. В тази част от урока ще преминем към практика и ще се опитаме да управляваме настройките на нашето уеб приложение чрез този файл.
Първо, нека се запознаем със специалния класWebConfigurationManager. Нека да преминем към определението на този клас и да видим от какво се състои. Този клас е в пространството на имената System.Web.Configuration. Виждаме определен набор от свойства и методи, някои от които са претоварени. Класът е доста прост.
За да работим с конфигурационния файл Web.config, ще използваме следните членове:
AppSettings – Това свойство връща стандартна колекция NameValueCollection, която е колекция от прости настройки на приложението. Можете да получите достъп до стойността на конкретен елемент в секциятаappSettings на файла Web.config. чрез достъп по ключ или по индекс.
ConnectionStrings - Това свойство връща колекция от обекти на класа ConnectionStringSettings. Този клас описва специфичен низ за свързване към външен източник на данни, като например база данни.
GetWebApplicationSection(section) - този метод връща обект, с който можете да получите информация за конкретен раздел в конфигурационния файл и вече по някакъв начин да работите с неговите специфични атрибути.
Сега нека се опитаме да направим промени във файла Web.config. Да кажем, че трябва да добавим наши собствени персонализации към приложението. Вече знаем, че не е добра идея да кодирате твърдо нови настройки, например чрез константи. Затова ще ги добавим към конфигурационния файл Web.config.
Например в нашия проект ще работим с различни държави, градове и часови зони. Трябва да добавим градпо подразбиране и часовата зона по подразбиране, така че в този случай тези данни да могат да се използват в процеса на работа.
В този случай, когато новият конфигурационен елемент не е сложна логическа структура, ще се обърнем към секцията appSettings. Този раздел съдържа прости конфигурационни елементи тип ключ/стойност. Нека добавим два нови елемента тук - града по подразбиране и часовата зона по подразбиране:
Сега, чрез класа WebConfigurationManager, можем да получим достъп до секцията appSettings и да прочетем новите настройки:
Има обаче един проблем с този подход. Ако искаме да опишем по-сложен конфигурационен модел, тогава ще трябва да запишем всяка нова настройка отделно като двойка ключ/стойност. Това може да направи файла Web.config много голям и неудобен за работа.
Нека се опитаме да създадем по-сложна структура като групата system.web. Тоест ще декларираме нова група, в която ще бъдат вложени отделни елементи с необходимите атрибути:
Работата с този тип конфигурация е малко по-сложна. Преди да можем да го използваме в производството, ще трябва да напишем код за поддръжка. Ще трябва да създадем класове манипулатори, които описват тази конфигурация програмно и също така да я регистрираме във файла Web.config.
Тоест, ние наследяваме от класа ConfigurationSection и вътре в нашия клас асоциираме свойства със съответните атрибути в секцията.
След това трябва да опишем по подобен начин групата userCustomSettings, която декларирахме, в която е вложен елементът defaultValues . Отново създаваме клас манипулатор, този път за групата:
След това трябва да регистрирате декларираната група и раздел във файла Web.config в секцията configSections:
Сега всички подготвителнистъпките са завършени и можем да прочетем нашата конфигурация:
Между другото, отбелязвам, че за да работим със стандартни секции и групи от файла Web.config, не е нужно да пишем клас манипулатор за всеки от тях. Тези класове вече съществуват, те могат да се използват за работа, те са в пространството на имената System.Web.Configuration.
Поради факта, че сме описали нашата конфигурация чрез класове манипулатори, сега можем програмно да управляваме тази конфигурация. Първо, можем да добавим персонализирани опции към конфигурационните атрибути:
Сега, ако премахнем атрибута timeZoneShift от конфигурацията, ще се използва стойността му по подразбиране 5. В същото време, ако премахнем атрибута city (който вече е задължителен), ще видим грешка в конфигурацията и нашето приложение няма да може да стартира.
Тоест чрез параметрите можем да гарантираме, че конфигурацията трябва да бъде правилно конфигурирана преди стартиране на приложението. Понякога това може да бъде много важно. Ще бъде много по-безопасно просто да не оставите приложението да стартира, отколкото да си набивате мозъка по-късно в процеса и да търсите някаква логическа грешка поради липсващата стойност на града.
Също така, в допълнение към тези параметри, можем да приложим допълнителни атрибути за валидиране към нашите свойства, които описват секцията в конфигурацията. По-долу е даден списък на всички налични атрибути:
CallbackValidator - използва се за прилагане на персонализирано валидиране (вижте по-долу).
StringValidator - използва се за прилагане на проста проверка на низови стойности. Например, ограничете дължината на низа.
IntegerValidator - използва се за прилагане на валидиране на int стойности. Например, ограничете броя до някакъв диапазон.
LongValidator - използва се за валидиране на дълги стойности.
TimeSpanValidator - използва се за валидиране на стойности на TimeSpan. Например, можете също да ограничите диапазона от стойности.
RegexStringValidator - може да се използва за проверка дали даден низ съответства на регулярен израз или не.
Един от по-интересните атрибути е атрибутът CallbackValidator. Това ни позволява да валидираме стойност спрямо нашите собствени условия. Ние декларираме метода, в който ще се извърши валидирането, предаваме името на този метод на валидатора и в момента, в който конфигурацията на приложението се зарежда, този метод ще бъде извикан, за да провери стойността в конфигурацията.
Нека напишем метод, в който ще проверим, че ако изпратеният имейл не съдържа думата admin, тогава хвърляме изключение, че изпратеният имейл не ни подхожда:
Обърнете внимание на важен момент. Особеността на валидиращите атрибути е, че валидаторите се извикват два пъти на проверка. Първият път, когато валидаторът получава стойността по подразбиране за дадения тип (празен низ за типа низ, 0 за типа int и т.н.). След това се извършва второто извикване на валидатора и стойността от файла Web.config вече е предадена. Ето защо първо проверяваме за празен низ в конструкцията if. Ако не обработим правилно извикването на двойния валидатор, нашето валидиране ще се провали.
Нека също да видим как можем да работим с низовете за свързване, посочени в конфигурацията за външни източници на данни. Първо, представете си, че имаме следния низ за връзка с база данни, деклариран в нашето приложение:
За да работим с низовете за свързване, посочени в конфигурацията, ние се отнасяме към класа WebConfigurationManager, към свойствотоConnectionStrings. Това свойство връща обект от класа ConnectionStringSettingsCollection, който съдържа колекция от всички декларирани низове за връзка:
Както можете да видите, работата с низовете за свързване е много проста и удобна. За да направите това, в класа WebConfigurationManager е дефинирано специално свойство.
Остава да разгледаме въпроса за замяната на конфигурацията за част от приложението. Това може да стане по два начина:
- чрез елемента местоположение във файла Web.config
- чрез вложен файл Web.config
Елементътlocation ни позволява да дефинираме отделни секции в конфигурационния файл, които ще бъдат извикани при достъп до конкретен URL адрес. Например, нека добавим персонализирани правила за действието Index в домашния контролер:
Сега, при достъп до този URL адрес, декларираната от нас конфигурация ще бъде заменена с нови стойности. Забележете, че другите елементи на секцията appSettings са наследени от родителската конфигурация във файла Web.config.
Можем също да създадем допълнителен файл Web.config в поддиректория на нашето приложение. Например, нека създадем конфигурационен файл в папката Views/Home:
За да приложим новите настройки от вложения файл Web.config, трябва да прочетем тази конфигурация през WebConfigurationManager:
Също така искам да отбележа, че можем не само да получим информация за текущите настройки на приложението, но и да променим настройките на приложението по време на изпълнение. Например:
В повечето случаи това не се препоръчва, тъй като подобни действия могат да доведат до различни грешки в приложението по време на изпълнение, загуба на данни и т.н.