Программное средство по обмену услугами для владельцев собак
Сравнение показателей ресурсов cenotavr.by и petonik.com. Редактирование объявлений, задание критериев отбора объявлений по фильтрам. Разработка проекта программного обеспечения для сайта услуг для животных, алгоритм редактирования и удаления питомца.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 09.07.2017 |
Размер файла | 2,8 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Кроме того при отображении диалога имеет смысл показывать информацию о пользователе, с которым авторизированный пользователь ведет переписку. Для хранения этой информации служит переменная usrToShow. Она получает значение mes.Receiver, если автор сообщения это авторизированный пользователь и значение mes.Author в противоположном случае. Далее в итерации переменной unViewed присваивается количество сообщений из БД, помеченных как непрочитанные и у которых получатель это зарегистрированный пользователь, а отправитель это пользователь usrToShow. Вся эта информация необходима для отображения информации о диалоге пользователя включая сам текст сообщения, информация о собеседник и количество непрочитанных авторизированным пользователем сообщений в этом диалоге. Пояснение по внешнему виду списка диалогов приведено на рисунке 26.
Рисунок 26 - Внешний вид списка диалогов пользователя
Рисунок 27 - Алгоритм отображения списков диалогов
4.5 Алгоритм подбора объявлений
Алгоритм подбора объявлений по заданным фильтрам представлен на рисунке 28. В приложении реализована возможность поиска объявлений по определенным критериям, а также возможность задавать порядок отображения подходящих объявлений. В случае, если пользователь изменил состояние одного из фильтров поиска объявлений, на сервер приходит текущее состояние всех фильтров и заданное пользователем состояние порядка отображения объявлений. Далее из БД извлекаются объявления, соответствующие этим фильтрам.
В случае если пользователем была определена сортировка по цене, полученные объявления сортируются по цене начиная от наименьшей, если была определена сортировка по дате, то объявления сортируются по дате начиная с самых новых, если была определена сортировка по рейтингу, то объявления сортируются по рейтингу, сформированному на основе отзывов и оценок других пользователей для этого объявления. Поскольку на сайте для разгрузки пропускных каналов реализована пагенация, то из результата отбирается первые pageSize. Далее проверяется информация о запросу. Если запрос типа ajax, то возвращается только часть разметки, касающаяся подобранных объявлений. Если тип запроса не ajax, то формируется и возвращается страница с результатами целиком.
Рисунок 28 - Алгоритм подбора объявлений
5. Тестирование программного средства
Тестирование программного обеспечения -- проверка соответствия между реальным и ожидаемым поведением программы, осуществляемая на конечном наборе тестов, выбранном определенным образом. В более широком смысле, тестирование -- это одна из техник контроля качества, включающая в себя активности по планированию работ (Test Management), проектированию тестов (Test Design), выполнению тестирования (Test Execution) и анализу полученных результатов (Test Analysis).Все методы тестирования можно условно разделить на две группы: тестирование по методу белого ящика и тестирование по методу черного ящика.
Разность этих подходов заключается в наличии доступа к исходному коду тестируемого ПО. Как можно догадаться из названий методов - при использовании «черного ящика» тестировщик использует только внешние рычаги взаимодействия с программой: с помощью пользовательского интерфейса или подключившись к тестируемой системе. При работе с «белым ящиком» тестировщик имеет доступ к коду, тем самым тестируя внутреннюю структуру программы.
Любое приложение необходимо тестировать. Качественное тестирование позволяет обнаружить ошибки и недочеты в работе программы на ранних этапах ее жизненного цикла, когда стоимость их исправления гораздо ниже, чем если бы приложение уже использовалось в работе пользователей. cenotavr petonik объявление животное
Для тестирования приложения был выбран метод черного ящика, тестирование производилось вручную. Был разработан набор smoke-тестов, призванных поверхностно проверить работоспособность системы, и набор criticalpath-тестов (функциональных тестов), целью которых является проверить работоспособность основного функционала приложения и его соответствие требованиям системы. Наборы тестов приведены ниже.
Разработаны 3 smoke-теста, которые предназначены для проверки общей работоспособности системы. Разработанные тесты описаны в таблице 5.
Таблица 5 -Smoke тесты
ID |
Модуль |
Подмодуль |
Описание теста |
Ожидаемый результат |
|
SM_T_1 |
Веб-риложение |
HomePage |
Запуск приложения: 1.Ввести адрес в адресную строку браузера |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления |
|
SM_T_2 |
Веб-риложение |
Authorization |
Вход в систему с корректными данными: 1.Ввести логин `jenik90@tut.by' и пароль `111111' 2.Нажать кнопку `Войти' |
1.Отобразится главная страница профиля в личном кабинете пользователя |
|
SM_T_3 |
Веб-риложение |
Authorization |
Вход с некорректными данными: 1.Ввести логин `notexist@tut.by' и пароль `111111' 2.Нажать кнопку `Войти' |
1.Поля формы заполнены введёнными данными. 2.Отображается сообщение о том, что логин или пароль введён неверно |
Также разработан набор функциональных тестов. Разработанные тесты приведены в таблице 6.
Размещено на http://www.allbest.ru/
Таблица 6 - Функциональные тесты
Иденти-фикатор |
Модуль |
Подмодуль/экран |
Описание теста |
Ожидаемый результат |
|
CP-Т_1 |
веб-приложение |
Search |
Поиск объявления по фильтрам, задать значения основным фильтрам 1.Перейти на домашнюю страницу 2.Выбрать категорию объявления 3.Выбрать город 4.Выбрать период для отображения 5.Задать на слайдере диапозон стоимости |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Отображается первая страница списка объявлений выбранной категории, на карте отображаются все объявления для данной категории, где задан атрибут адреса 3. Отображается первая страница списка объявлений для выбранной категории и данного города, на карте отображаются все подходящие элементы, где задан атрибут адреса 4.Отображается первая страница списка объявлений для выбранной категории, выбранного города соответствующих указанному периоду, на карте отображаются все подходящие элементы, где задан атрибут адреса 5. Отображается первая страница списка объявлений для выбранной категории, выбранного города соответствующих указанному периоду и диапозону цен, на карте отображаются все подходящие элементы, где задан атрибут адреса фильтрам возле заданного адреса |
|
CP-Т_2 |
веб-приложение |
Search |
Поиск объявления по фильтрам, задать значения основным и дополнительным фильтрам 1.Перейти на домашнюю страницу 2.Выбрать категорию объявления `Продажа собак' 3.Выбрать город 4.Выбрать период для отображения 5.Задать на слайдере диапозон стоимости 6. Нажать кнопку `Дополнительно' внизу блока фильтров 7. Выбрать породу из списка пород в появившемся блоке дополнительных параметров поиска 8.Выбрать пол в появившемся блоке дополнительных параметров |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Отображается первая страница списка объявлений выбранной категории, на карте отображаются все объявления для данной категории, где задан атрибут адреса 3. Отображается первая страница списка объявлений для выбранной категории и данного города, на карте отображаются все подходящие элементы, где задан атрибут адреса 4.Отображается первая страница списка объявлений для выбранной категории, выбранного города соответствующих указанному периоду, на карте отображаются все подходящие элементы, где задан атрибут адреса 5. Отображается первая страница списка объявлений для выбранной категории, выбранного города соответствующих указанному периоду и диапозону цен, на карте отображаются все подходящие элементы, где задан атрибут адреса фильтрам возле заданного адреса 6.Отображается блок дополнительных параметров поиска (по породе и полу) 7.Отображается первая страница объявлений, соответствующих всем предыдущим фильтрам а также выбранной породе, на карте отображаются все подходящие элементы, где задан атрибут адреса 8.Отображается первая страница объявлений, соответствующих всем предыдущим фильтрам а также выбранной породе и заданному полу, на карте отображаются все подходящие элементы, где задан атрибут адреса |
|
CP-Т_3 |
веб-приложение |
Search |
Проверка меток на карте 1.Перейти на домашнюю страницу 2.Задать произвольные значения фильтрам поиска 3.Кликнуть по любой метке на карте 4.Кликнуть кнопке `Подробнее' у всплывшего возле метки краткого описания объявления |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Отображается первая страница списка объявлений, подходящих заданным фильтрам, на карте отображаются все подходящие объявления, где задан атрибут адреса 3. Возле метки появляется блок с краткой информацией по объявлению 4.Отображается страница с подробной информацией по выбранному объявлению |
|
CP-Т_4 |
веб-приложение |
Sorting |
Проверка сортировки результатов 1.Перейти на домашнюю страницу 2.Задать произвольные значения фильтрам поиска 3.Под блоком карты рядом с полем `сортировать по' выбрать из списка значение `дате начать со старых' 4.Под блоком карты рядом с полем `сортировать по' выбрать из списка значение `цене начать с дешевых' 5.Под блоком карты рядом с полем `сортировать по' выбрать из списка значение `цене начать с дорогих' 6.Под блоком карты рядом с полем `сортировать по' выбрать из списка значение `рейтингу' |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Отображается первая страница списка объявлений, подходящих заданным фильтрам, на карте отображаются все подходящие объявления, где задан атрибут адреса 3. Отображается первая страница списка объявлений, подходящих заданным фильтрам и отсортированных по возрастанию по дате, на карте изменений не происходит 4. Отображается первая страница списка объявлений, подходящих заданным фильтрам и отсортированных по возрастанию по цене, на карте изменений не происходит 5. Отображается первая страница списка объявлений, подходящих заданным фильтрам и отсортированных по убыванию по цене, на карте изменений не происходит 6. Отображается первая страница списка объявлений, подходящих заданным фильтрам и отсортированных по убыванию по рейтингу, на карте изменений не происходит |
|
CP-Т_5 |
веб-приложение |
Authorization |
Вход в личный кабинет 1.Перейти на домашнюю страницу 2.В блоке входа в личный кабинет нажать кнопку `Войти' 3.В блоке входа в поле `email'ввести существующий логин 4.В блоке входа в поле `пароль' ввести неверный пароль 5.Нажать кнопку `Войти' 6.В блоке входа в поля `email' и `пароль' ввести корректные значения для логина и пароля и нажать кнопку `Войти' |
1. Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Возле поля `email' появляется сообщение о необходимости указания emaila, возле поля `пароль' появляется сообщение о необходимости указания пароля 3.Возле поля `email' сообщение об ошибке исчезает 4.Возле поля `пароль' сообщение об ошибке исчезает 5.В блоке входа появляется сообщение о неверном пароле 6.Отображается главная страница профиля личного кабинета |
|
CP-Т_6 |
веб-приложение |
Аccount |
Регистрация пользователя 1.Перейти на домашнюю страницу 2.Нажать на меню Регистрация 3.Ввести в поле' e-mail' лат. буквами значение по шаблону *@*.* 4.Ввести поле `Пароль' лат. значение не менее 6 знаков 5.Ввести в поле `подтвердите пароль' тот же пароль 6.Заполнить поля `Имя' и `Фамилия' буквенными значениями не менее 2-х символов 7.Выбрать пол, поставить чекбокс о согласии с условиями сайта 8.Нажать кнопку `Зарегистрироваться' |
1. Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления 2.Отображается страница с формой для регистрации пользователя 3.Отображается введенный email в поле email 4. В поле пароль отобразятся точки вместо вводимых символов |
|
CP-Т_7 |
веб-приложение |
Аccount |
Редактирование личных данных пользователя 1.Войти в существующий личный кабинет на сайте 2.Нажать кнопку `Редактировать' под фотографией-аватаркой на главной странице профиля 3.Заполнить поля в отобразившейся форме новыми корректными значениями 4.Нажать кнопку `Выбрать файл' для загрузки фотографии 5.В появившемся диалоговом окне выбрать файл фотографии и нажать кнопку `Открыть' 6.Нажать кнопку `Сохранить' |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится форма для редактирования личных данных со старыми значениями в полях для заполнения 3.В полях для заполнения появляются новые значения 4.Отобразится диалоговое окно для загрузки фотографии 5.На странице рядом с кнопкой `Выберите файл' появляется изображение выбранной в диалоговом окне фотографии, также рядом с кнопкой отображается имя загружаемого файла 6.Отображается главная страница профиля в личном кабинете пользователя с новыми значениями данных, в слайдере фотографий появляется новая загруженная фотография |
|
CP-Т_8 |
веб-приложение |
Аccount |
Добавление питомца в личном кабинете 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои питомцы' в левой боковой навигационной панели 3.Нажать ссылку `Создать питомца' в конце списка питомцев 4.Заполнить появившуюся форму корректными данными о питомце 5.Нажать ссылку `Добавить' возле метки `Награды' на форме 6.Заполнить появившееся поле информацией о награде 7.Повторить пункты 4-5 для создания у питомица списка наград 8.Нажать кнопку `Выбрать файл' для загрузки фотографии 9.В появившемся диалоговом окне выбрать файл фотографии и нажать кнопку `Открыть' 10.Нажать кнопку `Добавить фото' 11.Повторить пункты 8-10 несколько раз для подготовки нескольких фотографий для загрузки на сервер 12.Нажать кнопку `Сохранить' |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится списокпитомцев пользователя с краткой информацией по каждому из них 3.Отобразится форма для добавления нового питомца с пустыми полями 4.Поля заполняются введенными данными 5.Появиться поле для информации о награде 6.В появившемся поле отображается введенная информация 7.В блоке `Награды' появляется группа заполненных полей о наградах питомца 8.Отобразится диалоговое окно для загрузки фотографии 9.На странице рядом с кнопкой `Выберите файл' появляется изображение выбранной в диалоговом окне фотографии, также рядом с кнопкой отображается имя загружаемого файла 10.Появляется дополнительный блок для загрузки фотографии 11. В блоке `Фотографии' появляется группа выбранных для загрузки на сервер фотографий питомца 12.Отображается страница с подробной информацией о созданном питомце, на слайдере появляются загруженные фотографии |
|
CP-Т_9 |
веб-приложение |
Account |
Добавление объявления в личном кабинете 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои объявления' в левой боковой навигационной панели 3.Нажать ссылку `Добавить объявление' в конце списка объявлений 4.Заполнить появившуюся форму корректными данными о новом объявлении 5.Нажать кнопку `Выбрать файл' для загрузки фотографии 6.В появившемся диалоговом окне выбрать файл фотографии и нажать кнопку `Открыть' 7.Нажать кнопку `Добавить фото' 8.Повторить пункты 8-10 несколько раз для подготовки нескольких фотографий для загрузки на сервер 9.Нажать кнопку `Сохранить' |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список объявлений пользователя с краткой информацией по каждому из них 3.Отобразится форма для добавления нового объявления с незаполненными полями 4.Поля формы заполняются введенными данными 5.Отобразится диалоговое окно для загрузки фотографии 6.На странице рядом с кнопкой `Выберите файл' появляется изображение выбранной в диалоговом окне фотографии, также рядом с кнопкой отображается имя загружаемого файла 7.Появляется дополнительный блок для загрузки фотографии 8.В блоке `Фотографии' появляется группа выбранных для загрузки на сервер фотографий для объявления 9.Отображается страница с подробной информацией о созданном объявлении, на слайдере появляются загруженные фотографии |
|
CP-Т_10 |
веб-приложение |
Messages |
Отправка личного сообщения пользователю 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои друзья' в левой боковой навигационной панели 3.В отобразившемся списке пользователей нажать ссылку подробнее возле интересующего пользователя 4.Нажать кнопку `Отправить сообщение' под фотографией пользователя 5.Заполнить поле для текста сообщения и нажать кнопку `Отправить' 6.Нажать ссылку `Выйти' в блоке заголовка сайта 7.Ввести логин и пароль пользователя, которому было отправлено сообщение и нажать кнопку `Войти' 8.Нажать ссылку `Мои сообщения' в левой боковой навигационной панели 9.В отобразившемся списке диалогов нажать на диалог, где отправитель это предыдущий авторизированный пользователь |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список друзей пользователя с краткой информацией по каждому из них 3.Отобразится страница с подробной информацией о выбранном пользователе 4.Отобразится страница с историей переписки с данным пользователем и форма для отправки нового сообщения, состоящая из одного поля 5.Поле заполнится введенными данными и после нажатия `Отправить' появится как последнее сообщение в истории переписки, при этом поле для ввода сообщения станет пустым 6.Отобразится домашняя страница формой для входя в личный кабинет и ссылкой на регистрацию в левой боковой панели 7. Отобразится главная страница профиля в личном кабинете пользователя, возле ссылки `Мои сообщения отображена пометка с количеством непрочитанных сообщений' 8.Отображается список диалогов пользователя, отсортированный по убывания по времени, в каждом диалоге отображено последнее сообщение (или его начало, если сообщение длинное) в истории переписки, диалог с предыдущим авторизированным пользователем подсвечен затемненным фонов и имеет пометку с количеством непрочитанных в этом диалоге сообщений 9. Отображается история переписки с последним с предыдущим авторизированным пользователем, последнее сообщение в истории это сообщение отправленное на предыдущем этапе теста. Рядом со ссылкой `Мои сообщения' пометка количества непрочитанных сообщение уменьшается на число сообщение, которые были только что просмотрены в данном диалоге |
|
CP-Т_11 |
веб-приложение |
Messages |
Проверка уведомления о пришедшем сообщении вне режима работы с диалогом Для реализации теста необходима работа на двух компьютерах одновременно под двумя разными аккаунтами на сайте В ПЕРВОМ АККАУНТЕ : . 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои друзья' в левой боковой навигационной панели 3.В отобразившемся списке пользователей нажать ссылку подробнее возле пользователя обладателя второго аккаунта в тесте 4.Нажать кнопку `Отправить сообщение' под фотографией пользователя ВО ВТОРОМ АККАУНТЕ : . 5.Войти в личный кабинет на сайте В ПЕРВОМ АККАУНТЕ : 6.Заполнить поле для текста сообщения и нажать кнопку `Отправить' |
В ПЕРВОМ АККАУНТЕ : . 1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список друзей пользователя с краткой информацией по каждому из них 3.Отобразится страница с подробной информацией о выбранном пользователе 4.Отобразится страница с историей переписки с данным пользователем и форма для отправки нового сообщения, состоящая из одного поля ВО ВТОРОМ АККАУНТЕ : 5. Отобразится главная страница профиля в личном кабинете пользователя 6. В ПЕРВОМ АККАУНТЕ : . Поле заполнится введенными данными и после нажатия `Отправить' появится как последнее сообщение в истории переписки, при этом поле для ввода сообщения станет пустым ВО ВТОРОМ АККАУНТЕ : . Возле ссылки `Мои сообщения пометка с количеством непрочитанных сообщений'увеличивается на 1, а в случае отсутствия ранее непрочитанных сообщений становится равной `(+1)', кроме того срабатывает звуковой сигнал, оповещающий о пришедшем сообщении |
|
CP-Т_12 |
веб-приложение |
Messages |
Проверка уведомления о пришедшем сообщении в режиме работы с диалогом Для реализации теста необходима работа на двух компьютерах одновременно под двумя разными аккаунтами на сайте В ПЕРВОМ АККАУНТЕ : . 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои друзья' в левой боковой навигационной панели 3.В отобразившемся списке пользователей нажать ссылку подробнее возле пользователя обладателя второго аккаунта в тесте 4.Нажать кнопку `Отправить сообщение' под фотографией пользователя ВО ВТОРОМ АККАУНТЕ : . 5.Войти в личный кабинет на сайте 6. Нажать ссылку `Мои диалоги' в левой боковой навигационной панели 7. В списке диалогов выбрать диалог-переписку с пользователем обладателем первого аккаунта В ПЕРВОМ АККАУНТЕ: 8.Заполнить поле для текста сообщения и нажать кнопку `Отправить' |
В ПЕРВОМ АККАУНТЕ : . 1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список друзей пользователя с краткой информацией по каждому из них 3.Отобразится страница с подробной информацией о выбранном пользователе 4.Отобразится страница с историей переписки с данным пользователем и форма для отправки нового сообщения, состоящая из одного поля ВО ВТОРОМ АККАУНТЕ : 5. Отобразится главная страница профиля в личном кабинете пользователя 6. Отобразится список диалогов пользователя 7. Отображается история переписки второго и первого полоьзователя 8. В ПЕРВОМ АККАУНТЕ : . Поле заполнится введенными данными и после нажатия `Отправить' появится как последнее сообщение в истории переписки, при этом поле для ввода сообщения станет пустым ВО ВТОРОМ АККАУНТЕ : . срабатывает звуковой сигнал, оповещающий о пришедшем сообщении, в истории переписки появляется отправленное первым пользователем сообщение |
|
CP-Т_13 |
веб-приложение |
Profile |
Проверка удаления объявления пользователем 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои объявления' в левой боковой навигационной панели 3.Нажать кнопку `Подробнее' рядом с интересующим из списка объявлением 4.В открывшемся окне нажать кнопку `Удалить' 5.В появившемся диалоговом окне нажать кнопку `Отмена' 6.Повторить пункт 4 7.В появившемся диалоговом окне нажать кнопку `ОК' |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список объявлений пользователя с краткой информацией по каждому из них 3.Отобразится страница с подробной информацией о выбранном объявлении 4.Отобразится диалоговое окно о подтверждении удаления 5. Отобразится страница с подробной информацией об объявлении, удаление произведено не будет 6. Отобразится диалоговое окно о подтверждении удаления 7.Отобразится список объявлений пользователя без удаленного объявления |
|
CP-Т_14 |
веб-приложение |
Profile |
Проверка удаления питомца пользователем 1.Войти в личный кабинет на сайте 2.Нажать ссылку `Мои питомцы' в левой боковой навигационной панели 3.Нажать кнопку `Подробнее' рядом с интересующим из списка питомцем 4.В открывшемся окне нажать кнопку `Удалить' 5.В появившемся диалоговом окне нажать кнопку `Отмена' 6.Повторить пункт 4 7.В появившемся диалоговом окне нажать кнопку `ОК' |
1.Отобразится главная страница профиля в личном кабинете пользователя 2.Отобразится список питомцев пользователя с краткой информацией по каждому из них 3.Отобразится страница с подробной информацией о выбранном питомце 4.Отобразится диалоговое окно о подтверждении удаления 5. Отобразится страница с подробной информацией о питомце, удаление произведено не будет 6. Отобразится диалоговое окно о подтверждении удаления 7.Отобразится список питомцев пользователя без удаленного объявления |
|
CP-Т_15 |
веб-приложение |
Sorting |
Проверка страничной пагинации 1.Перейти на домашнюю страницу 2.Задать произвольные значения фильтрам поиска 3.Нажать внизу страницы ссылку на 2-ую страницу 4.Нажать внизу страницы ссылку на 4-ую страницу 5.Нажать внизу страницы ссылку на последнюю страницу 6.Нажать внизу страницы ссылку на 1-ую страницу |
1.Отображается домашняя страница с картой и боковой панелью поиска и первой страницей списка объявлений по умолчанию, на карте отображаются все объявления, внизу страницы ссылка на первую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) 2.Отображается первая страница списка объявлений, подходящих заданным фильтрам, на карте отображаются все подходящие объявления, где задан атрибут адреса , внизу страницы ссылка на первую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) 3. Отображается вторая страница списка объявлений, подходящих заданным фильтрам, на карте изменений не происходит, внизу страницы ссылка на вторую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) 4. Отображается четвертая страница списка объявлений, подходящих заданным фильтрам, на карте изменений не происходит, внизу страницы ссылка на 4-ую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) 5. Отображается последняя страница списка объявлений, подходящих заданным фильтрам, на карте изменений не происходит, внизу страницы ссылка на последнюю страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) 6. Вновь отображается первая страница списка объявлений, подходящих заданным фильтрам, на карте изменений не происходит, внизу страницы ссылка на первую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый) |
Размещено на http://www.allbest.ru/
Указанный набор тестов был составлен на основании требований к системе. Тестовые сценарии были разработаны для проверки работы конкретного функционала, необходимость реализации которого была определена в спецификации требований. Приведенные выше тесты были успешно выполнены, выявленные в ходе выполнения тестов ошибки были устранены. В результате программная система успешно прошла этап тестирования и соответствует спецификации требований.
Заключение
В данном дипломном проекте было разработано веб-приложение, реализующее площадку для обмена услугами для владельцев собак.
Был произведен глубокий анализ предметной области, разработана спецификация требований к системе, выявлены бизнес-акторы и их функции. Были определены основные варианты использования системы в рамках действий бизнес-акторов и выявлен основной функционал приложения для его реализации. Полученное в результате приложение позволяет пользователям создавать на сайте личный кабинет, в котором предоставляется возможность создавать страницы своим питомцам а также публиковать объявления в различных рубриках. Реализована возможность оставлять отзывы объявлениям, а также возможность обмена личными сообщениями.
Полученное в итоге приложение имеет многоуровневую архитектуру (модель представления, модель бизнес-логики, модель данных). Каждый уровень является изолированным и мало связан логически с другими уровнями. Связь уровней осуществляется через реализацию интерфейсов, что позволяет легко модифицировать приложение, вносить изменение и заменять некоторые модули программы на другие без серьезных проблем с перестроением приложения и рефакторингом. Так например можно легко заменить модель данных, используя в качестве хранилища не БД а XML-файл или CSV-файл. Для этого лишь надо реализовать несколько публичных интерфейсов, избегая при этом масштабного рефакторинга кода.
Приложение следует дополнить некоторым функционалом характерным для социальных сетей: следует добавить ленту новостей, реализовать возможность создания групп пользователей по интересам. На страницах пользователей и питомцев следует добавить альбомы с фотографиями, что позволит пользователю группировать фотографии по некоторому признаку.
Также следует предоставить возможность создавать личный кабинет для юридических лиц. Такой личный кабинет должен обладать более широким функционалом. Кроме того следует создать раздел энциклопедий, где можно будет найти любую полезную информацию. В такой раздел следует включить подробную справку по различным пародам собак, советы по уходу за собаками и их воспитанию.
В ходе работы над проектом были приобретены практические навыки использования таких технологий как ASP.NET MVC5, JQuery, JavaScript. Также были изучены основы работы с Entity Framework 6, Ajax, DI (Dependency Injection), Html и CSS. Кроме того в проекте использовалось сторонний API (Yandex maps) и были получены навыки работы с ним. Также использовались некоторые специфичные библиотеки JavaScript (слайдер фотографий, слайдер для диапозона цен, диалоговые окна).
Список использованных источников
1. Фримен, А. ASP.NET MVC 4 с примерами на C# 5.0 для профессионалов. 4-е изд. - Россия : Вильямс, 2013. - 688 с.
2. Фримен, А. JQuery для профессионалов- Москва-Питер-Киев: Вильямс, 2013. - 953 с.
3. Нейгел, К. C#5.0 и платформа .NET 4.5 для профессионалов-СПб: Москва-Питер-Киев: Вильямс, 2014. - 1435 с.
4. Рихтер, Д. CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#. - СпБ. : Питер, 2013. - 896 с
5. Дейт Дж. Кристофер Введение в системы баз данных. - М.: дом "Вильяме", 2005. - 8-е издание 1328 с.
6. Герберт Шилдт. C# 4.0: полное руководство - М.: «Вильямс», 2011. - 1056 с.
7. Yandex Maps APIs [Электронный ресурс]. - Режим доступа: https://tech.yandex.ru/maps/
8. Bootstrap 3 [Электронный ресурс]. - Режим доступа: http://getbootstrap.com/
9. Руководство по ASP.NET MVC 5 [Электронный ресурс]. - Режим доступа: http://metanit.com/sharp/mvc5/
10. Симан, М. Внедрение зависимостей в .NET. - СпБ. : Питер, 2013. -464 с.
11. Голдштейн, С. Оптимизация приложений на платформе .Net. /Голдштейн С., Зурбалев Д., Флатов И. - Россия : ДМК Пресс, 2014. - 524с.
12. Microsoft developer Network [Электронный ресурс]. - Режим доступа: https://msdn.microsoft.com/ru-ru/.
13. Тамре, Л. Введение в тестирование программного обеспечения / Л. Тамре - М.: Вильямс, 2003 - 368с.
Приложение А
Код программы
using System;
using System.Collections.Generic;
using System.Linq;
using MyPet.Domain.Abstract;
using MyPet.Domain.Entities;
using System.Data.Entity;
namespace MyPet.Domain.Concrete
{
public class AdvRepository : IRepository<Advertizement>
{
private EFDbContext context = new EFDbContext();
public IEnumerable<Advertizement> GetAll()
{
return context.Advertizements.Include("Category").Include("DogBreed").Include("AdvertizementOwner");
}
public Advertizement Get(int id)
{
return context.Advertizements.Include("Category").Include("DogBreed").Include("AdvertizementOwner").FirstOrDefault(x=>x.AdvertizementId==id);
}
public void Create(Advertizement adv)
{
context.Advertizements.Add(adv);
}
public void Update(Advertizement adv)
{
context.Entry(adv).State = EntityState.Modified;
}
public IEnumerable<Advertizement> Find(Func<Advertizement, Boolean> predicate)
{
return context.Advertizements.Include("Category").Include("DogBreed").Include("AdvertizementOwner").Where(predicate).ToList();
}
public void Delete(int id)
{
Advertizement adv = context.Advertizements.Find(id);
if (adv != null)
context.Advertizements.Remove(adv);
}
public void Save()
{
context.SaveChanges();
}
}
}
using MyPet.Domain.Entities;
using System.Data.Entity;
usinSystem.Data.Entity.ModelConfiguration.Conventions;
namespace MyPet.Domain.Concrete
{
public class EFDbContext : DbContext
{
public DbSet<Reward> Rewards { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<DogBreed> DogBreeds { get; set; }
public DbSet<Profile> Profiles { get; set; }
public DbSet<Pet> Pets { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<Friend> Friends { get; set; }
public DbSet<Advertizement> Advertizements { get; set; }
public DbSet<AdvertizementCategory> AdvertizementCategories { get; set; }
public DbSet<Review> Reviews { get; set; }
}
}
using System.Linq;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Security.Claims;
using System.Data.Entity;
using Microsoft.Owin.Security;
using MyPet.WebUI.Models.ViewModels; // пространство имен LoginViewModel
using MyPet.Domain.Entities; // пространство имен моделей
using MyPet.Domain.Concrete;
using MyPet.Domain.Abstract;
using System.Threading.Tasks;
using MyPet.WebUI.Models;
using System.IO;
using System;
using ImageResizer;
using System.Text.RegularExpressions;
namespace MyPet.WebUI.Controllers
{
public class AccountController : Controller
{
private IMyPetRepository repository;
private IRepository<User> userRepository;
private IRepository<Profile> profRepository;
public AccountController(IRepository<User> userRepo, IMyPetRepository repoAll, IRepository<Profile>profRepo )
{
this.userRepository = userRepo;
this.repository = repoAll;
this.profRepository = profRepo;
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
User user = userRepository.GetAll().FirstOrDefault(u => u.Email == model.Email && u.Password == model.Password);
if (user == null)
{
ModelState.AddModelError("", "Неверный логин или пароль.");
}
else
{
this.Authorise(user);
return RedirectToAction("Details", new { id=user.UserId});
}
}
return View(model);
}
public ActionResult Logout()
{
AuthenticationManager.SignOut();
return RedirectToAction("List", "Advertizements");
}
[NonAction]
private ActionResult UserProfile(int id=0) // bottlenick!! The aportunity to authorise not through login-password
{
if (!Request.IsAuthenticated)
{
User curUser=userRepository.Get(id);
this.Authorise(curUser);
}
id = User.Identity.GetUserId<int>();
return RedirectToAction("Details", new { id});
}
public ActionResult List(int id=0)
{
if (id == 0)
return View(userRepository.GetAll().Select(x=>x.Profile));
else
{
var user = userRepository.Find(x => x.UserId == id);
if (user != null)
{
return View(user.Select(x => x.Profile));
}
else
return RedirectToAction("UserProfile", "Account", new { id = User.Identity.GetUserId<int>() });
}
}
[Authorize]
public ActionResult Details(int id)
{
var user = userRepository.Get(id);
this.FillViewBag(id);
string path = Server.MapPath(String.Concat("~/ProfilePhotos/", user.UserId.ToString().Trim(), "/").Trim());
string avatarPath = String.Concat("small", this.GetMinNumberInFileNames(path).ToString()).Trim();
TempData["AvatarPath"] = avatarPath;
if (user != null)
return View(user.Profile);
else return
RedirectToAction("Details", "Account", new { id = User.Identity.GetUserId<int>() });
}
[Authorize]
public ActionResult Edit()
{
int id = User.Identity.GetUserId<int>();
var prof = userRepository.Get(id).Profile;
if (prof != null)
{
ViewBag.Cities = new string[] { "Минск" }.Concat(repository.Advertizements.Select(x => x.City).OrderBy(x => x)).Distinct();
return View(prof);
}
else return
RedirectToAction("Details", "Account", new { id = User.Identity.GetUserId<int>() });
}
[HttpPost]
[Authorize]
public ActionResult Edit(Profile prof, HttpPostedFileBase[] uploads)
{
int id = User.Identity.GetUserId<int>();
if (ModelState.IsValid && prof.UserId == id)
{
if (uploads.Where(x => x!=null).FirstOrDefault() != null && prof.HaveImages == false)
prof.HaveImages = true;
profRepository.Update(prof);
profRepository.Save();
prof = profRepository.Get(prof.UserId);
try
{
if (uploads != null && uploads.Where(x => x!=null).FirstOrDefault() != null)
{
string path = Server.MapPath(String.Concat("~/ProfilePhotos/", prof.UserId.ToString().Trim(), "/").Trim());
int i = this.GetMaxNumberInFileNames(path) + 1;
foreach (var upload in uploads)
{
if (upload != null)
{
if (upload.ContentLength > 0)
{
var versions = new Dictionary<string, string>();
//Define the versions to generate
versions.Add("big", "maxwidth=768&maxheight=1024&format=jpg");
versions.Add("small", "maxwidth=240&maxheight=320&format=jpg");
versions.Add("tiny", "&maxheight=108&format=jpg");//maxwidth=81
//Generate each version
foreach (var suffix in versions.Keys)
{
upload.InputStream.Seek(0, SeekOrigin.Begin);
//Let the image builder add the correct extension based on the output file type
ImageBuilder.Current.Build(
new ImageJob(upload.InputStream,
String.Concat(path, suffix, i.ToString()),
new Instructions(versions[suffix]),
false, true));
}
}
i++;
}
}
}
}
catch (NullReferenceException) { }
return RedirectToAction("Details", new { id = prof.UserId });
}
else
{
ViewBag.Cities = new string[] { "Минск" }.Concat(repository.Advertizements.Select(x => x.City).OrderBy(x => x)).Distinct();
return View(prof);
}
}
[Authorize]
public ActionResult EditProfileAjax()
{
int id = User.Identity.GetUserId<int>();
var prof = userRepository.Get(id).Profile;
ViewBag.Cities = new string[] { "Минск" }.Concat(repository.Advertizements.Select(x => x.City).OrderBy(x => x)).Distinct();
if (prof != null)
return PartialView(prof);
else return
RedirectToAction("UserProfile", "Account", new { id });
}
[HttpPost]
[Authorize]
public ActionResult EditProfileAjax(Profile prof)
{
int id=User.Identity.GetUserId<int>();
if (ModelState.IsValid && prof.UserId==id)
{
userRepository.Get(id).Profile = prof;
userRepository.Save();
this.FillViewBag(id);
return PartialView("DetailsPartial", userRepository.Get(prof.UserId).Profile);
}
ViewBag.Cities = new string[] { "Минск" }.Concat(repository.Advertizements.Select(x => x.City).OrderBy(x => x)).Distinct();
return PartialView(prof);
}
[ValidateAntiForgeryToken]
private void Authorise(User user)
{
ClaimsIdentity claim = new ClaimsIdentity("ApplicationCookie", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
claim.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString(), ClaimValueTypes.String));
claim.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, user.Email, ClaimValueTypes.String));
claim.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
"OWIN Provider", ClaimValueTypes.String));
if (user.Role != null)
claim.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, user.Role.Name, ClaimValueTypes.String));
AuthenticationManager.SignOut();
AuthenticationManager.SignIn(new AuthenticationProperties{IsPersistent = true}, claim);
}
private void FillViewBag(int id)
{
var pets = repository.Pets.Where(x => x.UserId == id);
ViewBag.Pets = pets;
var advs = repository.Advertizements.Where(x => x.AdvertizementOwnerId == id);
ViewBag.Advs = advs;
}
public PartialViewResult Vidget()
{
int userId;
Profile profile=null;
string name;
if (Request.IsAuthenticated && int.TryParse(User.Identity.GetUserId<int>().ToString(), out userId))
{
profile = userRepository.Get(userId).Profile;
}
if (profile != null)
name = profile.FirstName + " " + profile.LastName;
else name = null;
return PartialView((object)name);
}
public ActionResult GetImg(string id)
{
FileInfo file=new FileInfo(Server.MapPath("~/Avatars/default.jpg"));
if (id != null)
{
string[] strs = id.Split(new char[] { '-' });
if (strs.Length == 2 && (new FileInfo(Server.MapPath(String.Concat("~/ProfilePhotos/", strs[0].Trim(), "/", strs[1], ".jpg").Trim()))).Exists)
{
file = new FileInfo(Server.MapPath(String.Concat("~/ProfilePhotos/", strs[0].Trim(), "/", strs[1], ".jpg").Trim()));
}
else
{
Profile prof=profRepository.Find(x=>x.UserId==int.Parse(strs[0])).FirstOrDefault();
if (prof.Sex)
file = new FileInfo(Server.MapPath("~/Avatars/default.jpg"));
else
file = new FileInfo(Server.MapPath("~/Avatars/default2.jpg"));
}
}
if (file.Exists)
return File(file.FullName, "text/plain", file.Name);
else return Content("");
}
[Authorize]
[HttpPost]
public ActionResult DeletePhoto(DeletePhotoModel delPhModel)
{
int authUserId = User.Identity.GetUserId<int>();
if (delPhModel.WhoCanDeleteId == authUserId && delPhModel.OwnerId != 0 && delPhModel.PhotoNumber != 0)
{
DirectoryInfo di = new DirectoryInfo(Server.MapPath(String.Concat("~/ProfilePhotos/", delPhModel.OwnerId.ToString().Trim()).Trim()));
if (di.Exists)
{
foreach (var file in di.GetFiles())
{
int fotoNumberLenght = delPhModel.PhotoNumber.ToString().Length;
int fileNameLength = Path.GetFileNameWithoutExtension(file.Name).Length;
if (file.Name.Contains(delPhModel.PhotoNumber.ToString()) &&
(Path.GetFileNameWithoutExtension(file.Name).LastIndexOf(delPhModel.PhotoNumber.ToString()) == fileNameLength - fotoNumberLenght))
{
file.Delete();
}
}
if (di.GetFiles().Length == 0)
{
di.Delete();
var prof = profRepository.Find(x => x.UserId == delPhModel.OwnerId).FirstOrDefault();
if (prof != null)
prof.HaveImages = false;
profRepository.Save();
}
}
}
return null;
}
private int GetMaxNumberInFileNames(string path)
{
//var path = Server.MapPath(String.Concat("~/ProfilePhotos/", prof.UserId.ToString().Trim(), "/").Trim());
Directory.CreateDirectory(path);
DirectoryInfo di = new DirectoryInfo(path);
Regex r = new Regex(@"\d+");
string ddd = di.GetFiles().Select(x => x.Name).FirstOrDefault();
Match teg;
int maxNumberInFileNames = 0;
foreach (string fileName in di.GetFiles().Select(x => x.Name))
{
teg = r.Match(fileName);
if (teg.Success && int.Parse(teg.ToString()) > maxNumberInFileNames)
maxNumberInFileNames = int.Parse(teg.ToString());
}
return maxNumberInFileNames;
}
private int GetMinNumberInFileNames(string path)
{
Directory.CreateDirectory(path);
DirectoryInfo di = new DirectoryInfo(path);
Regex r = new Regex(@"\d+");
string ddd = di.GetFiles().Select(x => x.Name).FirstOrDefault();
Match teg;
int minNumberInFileNames = int.MaxValue;
foreach (string fileName in di.GetFiles().Select(x => x.Name))
{
teg = r.Match(fileName);
if (teg.Success && int.Parse(teg.ToString()) < minNumberInFileNames)
minNumberInFileNames = int.Parse(teg.ToString());
}
return minNumberInFileNames==int.MaxValue?0:minNumberInFileNames;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MyPet.Domain.Abstract;
using MyPet.Domain.Entities;
using MyPet.WebUI.Models;
using MyPet.WebUI.Models.ViewModels;
using System.IO;
using ImageResizer;
namespace MyPet.WebUI.Controllers
{
public class AdvertizementsController : Controller
{
// GET: Advertizements
private IMyPetRepository repository;
private IRepository<Advertizement> advRepository;
public int PageSize = 3;
public AdvertizementsController(IMyPetRepository repo, IRepository<Advertizement> advrepo)
{
this.repository = repo;
this.advRepository = advrepo;
}
public ActionResult MyAdvs(int? id)
{
if (id == null)
id = User.Identity.GetUserId<int>();
var advs = advRepository.Find(x => x.AdvertizementOwnerId == id);
if (advs != null)
return View(advs);
else
return RedirectToAction("List");
}
public ActionResult Details(int id)
{
var adv = advRepository.Get(id);
List<string[]> advPhotos=null;
if (adv != null)
{
DirectoryInfo dir = new DirectoryInfo(Server.MapPath(String.Concat("~/AdvPhotos/", id).Trim()));
if(dir!=null && dir.Exists)
{
advPhotos = new List<string[]>();
IEnumerable<FileInfo> files = dir.GetFiles();
string[] curFiles;
int filesGroupCount=files.Where(x=>x.Name.Contains("tiny")).Count();
for(int i=1; i<filesGroupCount+1; i++)
{
curFiles = new string[3];
curFiles[0] = Path.GetFileNameWithoutExtension(files.FirstOrDefault(x => x.Name.Contains("big") && x.Name.Contains(i.ToString())).Name);
curFiles[1] = Path.GetFileNameWithoutExtension(files.FirstOrDefault(x => x.Name.Contains("small") && x.Name.Contains(i.ToString())).Name);
curFiles[2]=Path.GetFileNameWithoutExtension(files.FirstOrDefault(x=>x.Name.Contains("tiny") && x.Name.Contains(i.ToString())).Name);
advPhotos.Add(curFiles);
}
}
TempData["AdvPhotos"] = advPhotos;
ViewBag.ReviewsCount = (repository.Reviews.Where(x => x.AdvertizementId == adv.AdvertizementId).Count());
ViewBag.AdvsCount = advRepository.Find(x => (x.AdvertizementOwnerId == adv.AdvertizementOwnerId) && (x.AdvertizementId != id)).Count();
return View(adv);
}
else return
RedirectToAction("Details", "Account", new { id = User.Identity.GetUserId<int>() });
}
public ActionResult Create()
{
Advertizement adv = new Advertizement();
ViewBag.Categories = repository.AdvertizementCategories;
ViewBag.DogBreeds = repository.DogBreeds;
return View(adv);
}
[HttpPost]
public ActionResult Create(Advertizement adv, HttpPostedFileBase[] uploads)
{
if (ModelState.IsValid)
{
adv.DateAndTime = DateTime.Now;
adv.AdvertizementOwnerId = User.Identity.GetUserId<int>();
adv.City = repository.Profiles.FirstOrDefault(x => x.UserId == User.Identity.GetUserId<int>()).City;
if (uploads.Where(x => x.ContentLength > 0).FirstOrDefault() != null)
adv.HaveImages = true;
advRepository.Create(adv);
advRepository.Save();
adv = advRepository.Get(adv.AdvertizementId);
if (uploads!=null && uploads.Where(x=>x.ContentLength>0).FirstOrDefault()!=null)
{
var path = Server.MapPath(String.Concat("~/AdvPhotos/", adv.AdvertizementId.ToString().Trim(), "/").Trim());
Directory.CreateDirectory(path);
int i=1;
foreach(var upload in uploads)
{
if(upload.ContentLength>0)
{
var versions = new Dictionary<string, string>();
//Define the versions to generate
versions.Add("big", "maxwidth=768&maxheight=1024&format=jpg");
versions.Add("small", "maxwidth=240&maxheight=320&format=jpg");
versions.Add("tiny", "&maxheight=108&format=jpg");//maxwidth=81
//Generate each version
foreach (var suffix in versions.Keys)
{
upload.InputStream.Seek(0, SeekOrigin.Begin);
//Let the image builder add the correct extension based on the output file type
ImageBuilder.Current.Build(
new ImageJob( upload.InputStream,
String.Concat(path, suffix, i.ToString()),
new Instructions(versions[suffix]),
false,true));
}
}
i++;
}
}
ViewBag.Advs = advRepository.Find(x => x.AdvertizementOwnerId == adv.AdvertizementOwnerId);
return RedirectToAction("Details", new { id=adv.AdvertizementId});
}
else
{
ViewBag.Categories = repository.AdvertizementCategories;
ViewBag.DogBreeds = repository.DogBreeds;
return View(adv);
}
}
public ActionResult Edit(int id)
{
var adv = advRepository.Get(id);
if (adv != null)
{
ViewBag.Categories = repository.AdvertizementCategories;
ViewBag.DogBreeds = repository.DogBreeds;
return View(adv);
}
else return
RedirectToAction("Details", "Account", new { id = User.Identity.GetUserId<int>() });
}
[HttpPost]
public ActionResult Edit(Advertizement adv, HttpPostedFileBase[]uploads)
{
if (ModelState.IsValid)
{
adv.DateAndTime = DateTime.Now;
adv.City = repository.Profiles.FirstOrDefault(x => x.UserId == User.Identity.GetUserId<int>()).City;
if (uploads.Where(x => x != null).FirstOrDefault() != null && adv.HaveImages == false)
adv.HaveImages = true;
advRepository.Update(adv);
advRepository.Save();
adv = advRepository.Get(adv.AdvertizementId);
try
{
if (uploads != null && uploads.Where(x=>x.ContentLength>0).FirstOrDefault()!=null)
{
var path = Server.MapPath(String.Concat("~/AdvPhotos/", adv.AdvertizementId.ToString().Trim(), "/").Trim());
Directory.CreateDirectory(path);
DirectoryInfo di = new DirectoryInfo(path);
int existingPhotoCount = di.GetFiles().Length / 3;
// здесь вместо i надо указать номер файла следующий за последним в директории
int i = existingPhotoCount + 1;
foreach (var upload in uploads)
{
if (upload != null)
{
if (upload.ContentLength > 0)
{
var versions = new Dictionary<string, string>();
//Define the versions to generate
versions.Add("big", "maxwidth=768&maxheight=1024&format=jpg");
versions.Add("small", "maxwidth=240&maxheight=320&format=jpg");
versions.Add("tiny", "&maxheight=108&format=jpg");//maxwidth=81
//Generate each version
foreach (var suffix in versions.Keys)
{
upload.InputStream.Seek(0, SeekOrigin.Begin);
//Let the image builder add the correct extension based on the output file type
ImageBuilder.Current.Build(
new ImageJob(upload.InputStream,
String.Concat(path, suffix, i.ToString()),
new Instructions(versions[suffix]),
false, true));
}
}
i++;
}
}
}
}
catch (NullReferenceException) { }
ViewBag.Advs = advRepository.Find(x => x.AdvertizementOwnerId == adv.AdvertizementOwnerId);
return RedirectToAction("Details", new { id = adv.AdvertizementId });
}
else
{
ViewBag.Categories = repository.AdvertizementCategories;
ViewBag.DogBreeds = repository.DogBreeds;
return View(adv);
}
}
//public ActionResult EditAjax(int id)
//{
// var adv = advRepository.Get(id);
// if (adv != null)
// {
// ViewBag.Categories = repository.AdvertizementCategories;
// ViewBag.DogBreeds = repository.DogBreeds;
// return PartialView(adv);
// }
// else return
// RedirectToAction("Details", "Account", new { id = User.Identity.GetUserId<int>() });
//}
//[HttpPost]
//public ActionResult EditAjax(Advertizement adv)
//{
// int id = User.Identity.GetUserId<int>();
// if (ModelState.IsValid && adv.AdvertizementOwnerId == id)
// {
// advRepository.Update(adv);
// advRepository.Save();
// adv = advRepository.Get(adv.AdvertizementId);
// return PartialView("DetailsPartial", adv);
// }
// return PartialView(adv);
//}
[Authorize]
public ActionResult Delete(int id)
{
var adv=advRepository.Get(id);
int userid = User.Identity.GetUserId<int>();
if (adv != null && adv.AdvertizementOwnerId == userid)
{
advRepository.Delete(id);
advRepository.Save();
var path = Server.MapPath(String.Concat("~/AdvPhotos/", id.ToString().Trim(), "/"));
DirectoryInfo di = new DirectoryInfo(path);
if(di!=null && di.Exists)
{
foreach (var file in di.GetFiles())
{
file.Delete();
}
di.Delete();
}
return RedirectToAction("MyAdvs");
}
else return RedirectToAction("DetailsPartial", "Account", new { id = userid });
}
[Authorize]
[HttpPost]
public ActionResult DeletePhoto(DeletePhotoModel delPhModel)
{
int authUserId = User.Identity.GetUserId<int>();
Подобные документы
Разработка приложения по обмену услугами для владельцев собак. Создание личного кабинета с персональными данными. Редактирование: личных данных, объявления, питомца. Алгоритм редактирования и удаления объявления. Тестирование данного программного средства
дипломная работа [2,8 M], добавлен 14.10.2016Автоматизация процесса создания рекламных объявлений и билбордов. Шаблон визитной карточки. Требования к аппаратным и операционным ресурсам компьютера, на котором будет разрабатываться программное приложение. Инструменты разработки. Интерфейс программы.
курсовая работа [734,1 K], добавлен 15.06.2013Анализ предметной области. Проектирование и разработка базы данных и интерфейса в виде набора Web-страниц для отображения, создания, удаления и редактирования записей базы данных. Аппаратное и программное обеспечение системы. Алгоритм работы программы.
курсовая работа [3,0 M], добавлен 12.01.2016Проектирование концептуальной, логической и физической модели базы данных. Формирование сущностей и связей между ними. Создание форм с функциями добавления, редактирования, удаления, поиска, печати. Разработка клиентской части БД с помощью среды Lazarus.
курсовая работа [1,3 M], добавлен 05.04.2015Выбор программного средства. Алгоритм разработки сайта. Установка системы управления контентом Joomla. Установка компонентов и плагинов. Тестирование программного продукта. Аппаратное и программное обеспечение. Техника безопасности на рабочем месте.
курсовая работа [4,5 M], добавлен 13.10.2012Проектирование модульной сетки. Позиционирование проекта и сегментация целевой аудитории. Краткое описание типов навигации, CMS и оптимизации. Разработка web-сайта с функцией форума, обратной связью и доской объявлений. Верстка сайта и его страниц.
дипломная работа [1,4 M], добавлен 12.12.2013Общее описание разрабатываемого веб-сайта. Создание модуля учета средств для разработки программного продукта. Разработка дизайна. Редактирование веб-сайта в CMS Worspress. Разработка методических указаний для продукта. Система управления базами данных.
дипломная работа [1,8 M], добавлен 10.07.2017Архитектура "клиент-сервер". Системный анализ базы данных "Газета объявлений", ее инфологическое и физическое проектирование. Программирование на стороне SQL-сервера. Разработка клиентской части в Borland C++ Builder 6.0 и с помощью Web-технологий.
курсовая работа [1,3 M], добавлен 07.07.2013Краткие сведения о доске объявлений, структура и внутреннее содержание соответствующего сайта. Принципы и основные этапы разработки, выбор и обоснование программных средств: язык HTML, каскадные таблицы стилей, JavaScript, Web-сервер Apache, PHP.
дипломная работа [1,6 M], добавлен 22.10.2014Разработка архитектуры сайта, структуры данных и необходимых программных модулей. Учет фирменного стиля компании при создании дизайна. Внедрение интерфейса административного редактирования сайта. Проведение экспериментального тестирования и отладки.
дипломная работа [3,0 M], добавлен 19.01.2017