У цій статті ми розглянемо допоміжні методи, які дозволяють упаковувати порції коду і розмітки так, що вони можуть багаторазово використовуватися в рамках програми ASP.NET MVC Framework. Ми почнемо з того, що покажемо, яким чином створювати власні допоміжні методи.
приклад програми
Для цілей цієї статті в Visual Studio створений новий проект MVC на ім'я HelperMethods з використанням шаблону Empty (Порожній) і відміткою прапорця MVC в розділі Add folders and core references for (Додати папки і основні посилання для). У проект доданий контролер Home, код якого показаний в прикладі нижче:
У методі дії Index () поданням передається пара масивів string через об'єкт ViewBag, а в якості об'єкта моделі зазначений тип string. В папці / Views / Home був створений файл уявлення Index.cshtml з вмістом, наведеними в прикладі нижче. Це строго типізовані уявлення (з типом моделі string) і в ньому не застосовується компоновка.
Щоб побачити, як візуалізується це уявлення, необхідно запустити додаток. Стандартна конфігурація маршрутизації, додана в проект середовищем Visual Studio, відобразить кореневої URL, автоматично запитаний браузером, на дію Index в контролері Home:
Створення спеціальних допоміжних методів
Ми збираємося пояснити роботу допоміжних методів на прикладі створення власної реалізації. У наступних розділах будуть показані два різних підходи до створення спеціальних допоміжних методів.
Створення вбудованого допоміжного методу
Найпростішим різновидом допоміжних методів є вбудований допоміжний метод, який визначається всередині уявлення. Ми можемо створити вбудовується допоміжний метод для спрощення нашого прикладу уявлення, використовуючи дескриптор @helper. як показано в прикладі нижче:
Подібно звичайним методам C #, що вбудовуються допоміжні методи мають імена і параметри. У цьому прикладі було визначено допоміжний метод на ім'я ListArrayStringItems (), який приймає як параметр строковий масив. Хоча вбудовується допоміжний метод виглядає схожим на метод, що повертає значення відсутній. Вміст тіла допоміжного методу обробляється і поміщається у відповідь, призначений для клієнта.
Зверніть увагу, що при використанні вбудованого допоміжного методу приводити динамічні властивості об'єкта ViewBag до строковому масиву не обов'язково. Одна з особливостей цього різновиду допоміжних методів пов'язана з оцінкою типів під час виконання.
У тілі вбудованого допоміжного методу застосовується той же самий синтаксис, що і в решті частині подання Razor. Літеральние рядки розглядаються як статична розмітка HTML, а оператори, які потребують обробки механізмом Razor, забезпечуються префіксами у вигляді символу @. Допоміжний метод в прикладі змішує статичну розмітку HTML і дескриптори Razor для перерахування елементів масиву, що дає в результаті такий же висновок, як і вихідне уявлення, але знижує дублювання в рамках уявлення.
Перевага такого підходу пов'язано з тим, що якщо знадобиться змінити спосіб відображення вмісту масиву, це доведеться робити тільки в одному місці. Як простий приклад в прикладі нижче показано, як замість простого висновку значень застосувати елементи ненумерованого списку HTML:
Зміни вносити довелося тільки в одному місці. Це може виглядати незначною перевагою в простому проекті, але є зручним способом збереження уявлень простими і узгодженими в реальному проекті. Результат проведених змін показаний на малюнку нижче:
Зверніть увагу, що в прикладі вище ключове слово foreach повинно мати префікс @, але в прикладі ще вище це не так. Причина в тому, що перший елемент в тілі допоміжного методу був змінений, щоб стати HTML-елементом, а це означає необхідність застосування символу @ для повідомлення механізму Razor про використання оператора C #. У попередньому прикладі не було ніяких HTML-елементів, тому механізм Razor припустив, що вміст являє собою код. Такі невеликі особливості кошти розбору можуть бути скрутними у відстеженні, але, на щастя, середа Visual Studio позначає помилки подібного роду.
Створення зовнішнього допоміжного методу
Вбудовувані допоміжні методи зручні, проте вони можуть використовуватися тільки усередині уявлення, в якому оголошено, і якщо такі методи включають занадто багато коду, то уявлення стає важким для читання.
Альтернативою є створення зовнішнього допоміжного методу HTML, який виражається як розширює метод C #. Зовнішні допоміжні методи можуть застосовуватися більш широко, проте вони дещо незручні в написанні, тому що в C # не підтримує елегантна генерація HTML-елементів. Для демонстрації цього кошти в приклад проекту додана папка Infrastructure, в яку поміщений новий файл класу на ім'я CustomHelpers.cs:
Створений тут допоміжний метод виконує ту ж саму функцію, що і вбудований допоміжний метод з попереднього прикладу - він отримує масив рядків і генерує HTML-елемент
- , що містить елемент
- для кожного рядка в масиві.
Першим параметром зовнішнього допоміжного методу HTML є об'єкт HtmlHelper. попереджання ключовим словом this, щоб повідомити компілятору C # про те, що визначається розширює метод C #. Об'єкт HtmlHelper надає доступ до інформації, яка може бути корисною при створенні вмісту, через властивості, описані в таблиці нижче:
Корисні властивості, певні в класі HtmlHelper
Повертає екземпляр реалізації IView, з якого був викликаний допоміжний метод
Інформація, яку можна отримати про запит, досить об'ємна, але здебільшого допоміжні методи прості і застосовуються для забезпечення узгодженого форматування. Ви можете використовувати вбудовані допоміжні методи для генерації специфічного для запитів вмісту (ці методи будуть описані в наступній статті) і часткові уявлення або дочірні дії для вирішення більш складних завдань.
Новий екземпляр TagBuilder створюється з передачею конструктору як параметр імені HTML-елемента, який повинен бути побудований. При використанні класу TagBuilder кутові дужки (<и>) Вказувати не потрібно, тобто елемент
- , наприклад, може бути створений таким чином:
- , і повертає його механізму візуалізації для вставки у відповідь.
Використання спеціального зовнішнього допоміжного методу
Спеціальний зовнішній допоміжний метод використовується трохи по-іншому, ніж вбудований метод. У прикладі нижче наведені зміни, внесені в файл /Views/Home/Index.cshtml з метою заміни вбудованого допоміжного методу зовнішнім варіантом:
Ми повинні забезпечити перебування простору імен, яке містить допоміжний розширює метод, в області видимості. Це робиться за допомогою дескриптора @using. але якщо розробляється багато спеціальних допоміжних методів, має сенс додати містять їх простору імен в файл /Views/Web.config, щоб вони завжди були доступними в уявленнях.
Дані передаються допоміжному методу, як якщо б він був вбудовуваним або методом C #, хоча необхідно подбати про приведення динамічних властивостей об'єкта ViewBag до типу, визначеному зовнішнім допоміжним методом, яким в даному випадку є масив string. Синтаксис не так елегантний, як використовуваний для вбудованих допоміжних методів, але це та частина ціни, яку доводиться платити за можливість створення допоміжного методу, що допускає застосування в будь-якому поданні проекту.
Коли слід використовувати допоміжні методи?
Тепер, коли відомо, як працюють допоміжні методи, виникає цілком резонне питання: коли їх слід використовувати замість часткових уявлень або дочірніх дій, особливо з урахуванням того, що підтримувані ними функціональні можливості перекриваються?
Я застосовую допоміжні методи тільки для скорочення обсягу дубльованого коду і розмітки в уявленнях, як це робилося в розглянутому прикладі, і тільки для самого простого вмісту. Для більш складної розмітки і вмісту я використовую часткові уявлення, а якщо необхідно виконувати будь-які маніпуляції з даними моделі, то дочірні дії. Я рекомендую дотримуватися такого ж підходу і намагатися зберігати допоміжні методи наскільки можливо простими. (Якщо мої допоміжні методи містять більше п'яти операторів C # або більше операторів C #, ніж HTML-елементів, то я віддаю перевагу частковим уявленням.)
Управління кодуванням рядків у допоміжному методі
Інфраструктура ASP.NET MVC Framework забезпечує захист від зловмисних даних, автоматично кодуючи їх так, що вони можуть бути безпечно додані на HTML-сторінку. Приклад такого кодування можна бачити в контролері Home розглянутого додатки, де поданням в якості об'єкта моделі передається потенційно ненадійна рядок:
Цей об'єкт моделі містить допустимий HTML-елемент, але коли значення візуалізується Razor, виходить наступна HTML-розмітка:
демонстрація проблеми
Щоб продемонструвати проблему, в класі CustomerHelpers створений новий допоміжний метод, як показано в прикладі нижче:
Цей допоміжний метод приймає рядок в якості параметра і генерує ту ж саму HTML-розмітку, яка включена в уявлення Index. За допомогою методу String.Format () генерується HTML-розмітка, яка передається у вигляді аргументу конструктору MvcHtmlString. У прикладі нижче показані зміни, внесені в уявлення /View/Home/Index.cshtml для використання нового допоміжного методу (крім того, проведені також зміни для виділення вмісту, яке надходить з цього допоміжного методу):
Запустивши додаток, можна побачити результат роботи нового допоміжного методу:
Допоміжному методу довірено генерувати безпечне вміст, що, на жаль, призводить до того, що браузер відображає елемент , а це поведінка може бути використано зловмисниками для порушення роботи програми.
Кодування вмісту допоміжного методу
Існує пара способів, за допомогою яких можна вирішити зазначену проблему, і вибір одного з них залежить від природи вмісту, що генерується допоміжним методом. Найпростіше рішення передбачає зміну повертається типу допоміжного методу на string, як показано в прикладі нижче. Це попереджає механізм візуалізації про те, що вміст не є безпечним і має бути закодовано перед додаванням до подання:
Такий прийом призводить до того, що Razor закодує весь вміст, що повертається допоміжним методом, породжуючи проблему в ситуації, коли генеруються HTML-елементи (як в розглянутому прикладі), але будучи дуже зручним в інших випадках. Результат можна бачити на малюнку:
Проблема з елементом вирішена, але елементи
також були закодовані, що абсолютно не підходить. У таких ситуаціях потрібна велика вибірковість, щоб кодувати тільки значення даних. У прикладі нижче показано, як це зробити:
У класі HtmlHelper визначено метод примірника на ім'я Encode (). який вирішує проблему і кодує строкове значення таким чином, що воно може бути безпечно включено в уявлення. Проблема, пов'язана з цим прийомом, полягає в тому, що потрібно не забувати застосовувати його. Всі значення даних явно кодуються на початку методу як нагадування і такий підхід потребує менше часу.
Результат описаного зміни показаний на малюнку:
Тут видно, що вміст, сгенерированное зовнішнім допоміжним методом, збігається з вмістом, що згенерував за рахунок використання значення моделі безпосередньо в поданні.
Схожі статті
Найбільш корисні члени класу TagBuilder описані в таблиці нижче:
Корисні методи і властивості, певні в класі TagBuilder
Метод або властивість
Властивість, яке дозволяє встановити в якості вмісту елемента HTML-рядок. Значення, вказане для цієї властивості, кодуватися не буде, тобто за допомогою даного властивості HTML-елементи можна вкладати один в одного
Встановлює текстовий вміст HTML-елемента. Параметр string кодується, щоб зробити вміст безпечним для відображення
MergeAttribute (string, string, bool)
Додає атрибут до HTML-елементу. Перший параметр - це ім'я атрибута, а другий - його значення. За допомогою параметра bool вказується, чи повинен бути замінений існуючий атрибут з тим же самим ім'ям
Результатом допоміжного методу HTML є об'єкт MvcHtmlString. вміст якого записується безпосередньо у відповідь, призначений клієнту. У розглянутому прикладі допоміжного методу результат виклику методу TagBuilder.ToString () передається конструктору нового об'єкта MvcHtmlString, як показано нижче:
Цей оператор генерує фрагмент HTML-розмітки, який містить елементи
- і
- , і повертає його механізму візуалізації для вставки у відповідь.