Інтернет магазин на MVC 5, Завантаження зображень з бази даних

ASP.NET --- Інтернет магазин --- Завантаження зображень із бази даних

На завершення інтерфейсу програми GameStore ми додамо дещо складнішу функціональність: ми дозволимо адміністратору завантажувати зображення товарів і зберігати їх у базі даних, щоб згодом вони відображалися в каталозі товарів. Сама по собі ця можливість не є особливо цікавою чи корисною, проте вона дозволить продемонструвати низку важливих функціональних засобів MVC Framework.

Розширення бази даних

Відкрийте вікно Server Explorer у Visual Studio і перейдіть до таблиці Games бази даних, створеної раніше. Може знадобитися змінити ім'я підключення до даних на EFDbContext, яке є ім'ям, призначеним для підключення у файлі Web.config. Середовище Visual Studio дещо непослідовне щодо перейменування підключення, тому ви можете побачити вихідне ім'я, яке відображалося під час створення підключення.

зображень

Клацніть правою кнопкою миші на таблиці Games і виберіть у контекстному меню пункт New Query (Новий запит) та введіть у текстовій області наступний оператор SQL:

Клацніть на кнопці Execute (Виконати), поміченій за допомогою стрілки, у лівому верхньому куті вікна і Visual Studio оновить базу даних, додавши два нових стовпці таблицю. Щоб протестувати оновлення, клацніть правою кнопкою на таблиці Games у вікні Server Explorer і виберіть у контекстному меню Open Table Definition (Відкрити визначення таблиці). Ви побачите, що тепер є стовпці з іменами ImageData і ImageMimeType, як показано на малюнку нижче:

завантаження

Якщо стовпці не видно, закрийте вікно візуального конструктора, клацніть правою кнопкою на підключенні доданих у вікні Server Explorer і виберіть у контекстному меню пункт Refresh (Оновити). Тепер після вибору пункту Open Table Definition у контекстному меню нові стовпці мають бути помітні.

Розширення моделі предметної галузі

До класу Game проекту GameStore.Domain необхідно додати два поля, відповідні стовпцям, які були додані в таблицю бази даних:

Переконайтеся, що імена властивостей, доданих до класу Game, точно збігаються з іменами нових стовпців у таблиці бази даних.

Створення елементів інтерфейсу для завантаження

Наступний крок полягає в додаванні підтримки обробки завантажень файлів. Це передбачає створення інтерфейсу користувача, за допомогою якого адміністратор зможе завантажувати зображення. Змініть уявлення Views/Admin/Edit.cshtml так, щоб воно відповідало прикладу:

Можливо, ви вже знаєте, що веб-браузери коректно завантажуватимуть файли, лише якщо в HTML-елементі для значенняатрибута enctype вказано multipart-form-data. Іншими словами, для успішного завантаження елемент повинен виглядати так:

Без атрибуту enctype браузер передаватиме лише ім'я файлу, але не його вміст, що зовсім не підходить для наших цілей. Щоб забезпечити наявність атрибуту enctype, необхідно використовувати перевантажену версію допоміжного методуHtml.BeginForm(), яка дозволяє вказувати атрибути HTML-елемента :

До вистави було внесено ще дві зміни. Перше - було замінено Razor-вираз if, що застосовується при генерації елементів за допомогою оператора. Результат залишився незмінним, але цей вираз дозволяє більш точно вказати властивості моделі, які мають бути пропущені, до того ж небажано відображати користувачевівластивості, що стосуються зображення.

Друга зміна пов'язана з додаванням елемента , атрибут type якого встановлений у файлі, щоб надати можливість завантаження файлів, поряд з елементом , який призначений для виведення зображення, пов'язаного з товаром, якщо воно є в базі даних.

Збереження зображень у базі даних

Ми повинні розширити версію POST методу дії Edit() у контролері Admin, щоб приймати завантажені дані зображення та зберігати їх у базі даних. Необхідні зміни наведено у прикладі нижче:

До методу Edit() було додано новий параметр, який MVC Framework використовує передачі даних завантаженого файлу методу дії. Ми перевіряємо значення цього параметра щодо рівності null, і якщо він не дорівнює null, то копіюємо дані і тип MIME з параметра в об'єкт Game, що в результаті призводить до збереження відомостей у базі даних. Крім того, необхідно оновити код класу EFGameRepository у проекті GameStore.Domain, забезпечивши збереження в базі даних значень, які були присвоєні властивостям ImageData та ImageMimeType. Необхідні зміни у методі SaveGame() показані в прикладі нижче:

Реалізація методу дії GetImage()

У прикладі представлення Edit.cshtml вище, було додано елемент , вміст якого виходить через метод дії GetImage() контролера Game. Ми збираємося реалізувати цей метод дії так, щоб мати можливість показувати зображення, що містяться у базі даних. У наведеному нижче прикладі наведено визначення згаданого методу дії:

Цей метод намагається знайти товар із ідентифікатором, значення якого вказано у параметрі. КласFileContentResult застосовується як результат методу дії, коли потрібно повернути файл клієнтському браузеру, аекземпляри створюються з допомогою методу File() базового класу контролера.

Модульне тестування: вилучення зображень

Ми повинні переконатися, що метод GetImage() повертає коректний тип MIME зі сховища, і що жодні дані не повертаються, якщо запитаний ідентифікатор товару не існує. Нижче наведено необхідні тестові методи, які визначені в новому файлі модульних тестів на ім'я ImageTests.cs.

Коли ми маємо справу з допустимим ідентифікатором товару, ми перевіряємо отримання результатуFileResult з методу дії та відповідність типу вмісту типу імітованих даних. Клас FileResult не дозволяє мати доступ до двійкового вмісту файлу, тому доведеться задовольнятися таким недостатньо надійним тестом. У разі запиту неприпустимого ідентифікатора товару, ми просто перевіряємо, що результатом є null.

Тепер адміністратор може завантажувати зображення для товарів. Ви можете перевірити це, запустивши програму, перейшовши на URL виду /Admin/Index і відредагувавши дані одного з товарів. На малюнку показано приклад.

бази

Виведення зображень товарів

Залишилося лише вивести зображення поряд із описами товарів у каталозі. Відредагуйте представлення Views/Shared/GameSummary.cshtml з урахуванням змін: