Программное средство по обмену услугами для владельцев собак

Разработка приложения по обмену услугами для владельцев собак. Создание личного кабинета с персональными данными. Редактирование: личных данных, объявления, питомца. Алгоритм редактирования и удаления объявления. Тестирование данного программного средства

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 14.10.2016
Размер файла 2,8 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Любое приложение необходимо тестировать. Качественное тестирование позволяет обнаружить ошибки и недочеты в работе программы на ранних этапах ее жизненного цикла, когда стоимость их исправления гораздо ниже, чем если бы приложение уже использовалось в работе пользователей.

Для тестирования приложения был выбран метод черного ящика, тестирование производилось вручную. Был разработан набор 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.

Таблица 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. В поле пароль отобразятся точки вместо вводимых символов

5. В поле `Подтвердите пароль' отобразятся точки вместо вводимых символов 6. Поля `Имя' и `Фамилия' заполнятся ответствующими значениями 7.Радиокнопка отобразится возле соответствующего значения пола, чекбокс пометится как отмеченный 8.Произойдет регистрация нового пользователя в системе и отобразится главная страница профиля зарегистрированного пользователя

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. Вновь отображается первая страница списка объявлений, подходящих заданным фильтрам, на карте изменений не происходит, внизу страницы ссылка на первую страницу будет подсвечена синим фоном и будет недоступна для нажатия, ссылки на остальные страницы будут иметь фон по умолчанию (белый)

Указанный набор тестов был составлен на основании требований к системе. Тестовые сценарии были разработаны для проверки работы конкретного функционала, необходимость реализации которого была определена в спецификации требований. Приведенные выше тесты были успешно выполнены, выявленные в ходе выполнения тестов ошибки были устранены. В результате программная система успешно прошла этап тестирования и соответствует спецификации требований.

Заключение

В данном дипломном проекте было разработано веб-приложение, реализующее площадку для обмена услугами для владельцев собак.

Был произведен глубокий анализ предметной области, разработана спецификация требований к системе, выявлены бизнес-акторы и их функции. Были определены основные варианты использования системы в рамках действий бизнес-акторов и выявлен основной функционал приложения для его реализации. Полученное в результате приложение позволяет пользователям создавать на сайте личный кабинет, в котором предоставляется возможность создавать страницы своим питомцам а также публиковать объявления в различных рубриках. Реализована возможность оставлять отзывы объявлениям, а также возможность обмена личными сообщениями.

Полученное в итоге приложение имеет многоуровневую архитектуру (модель представления, модель бизнес-логики, модель данных). Каждый уровень является изолированным и мало связан логически с другими уровнями. Связь уровней осуществляется через реализацию интерфейсов, что позволяет легко модифицировать приложение, вносить изменение и заменять некоторые модули программы на другие без серьезных проблем с перестроением приложения и рефакторингом. Так например можно легко заменить модель данных, используя в качестве хранилища не БД а 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;

using System.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>();

if (delPhModel.WhoCanDeleteId == authUserId && delPhModel.OwnerId!=0 && delPhModel.PhotoNumber!=0)

{

DirectoryInfo di = new DirectoryInfo(Server.MapPath(String.Concat("~/AdvPhotos/",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 adv=advRepository.Find(x => x.AdvertizementId == delPhModel.OwnerId).FirstOrDefault();

if (adv != null)

adv.HaveImages = false;

}

}

}

return null;

}

public ViewResult List()

{

return View();

}

public PartialViewResult GetAdvData(int id = 1)

{

PagingInfo pi = new PagingInfo { CurrentPage = id, ItemsPerPage = PageSize, TotalItems = advRepository.GetAll().Count() };

SearchInfo si = new SearchInfo

{

WayToSort = SortWay.MaxDatesFirst,

PagingInfo = pi

};

AdvsListViewModel model = new AdvsListViewModel { Advs = si.FilterAdvs(advRepository.GetAll()), PagingInfo = pi };

return PartialView(model);

}

public PartialViewResult Filter()

{

return PartialView(FillSearchInfoByLists(

new SearchInfo {PagingInfo=new PagingInfo

{

CurrentPage = 1,

ItemsPerPage = PageSize,

TotalItems = advRepository.GetAll().Count()

}, WayToSort=SortWay.MaxDatesFirst }));

}

[HttpPost]

public PartialViewResult Filter(SearchInfo si)

{

//System.Threading.Thread.Sleep(3000);

IEnumerable<Advertizement> advs =si.FilterAdvs(advRepository.GetAll());

PagingInfo pi = si.PagingInfo;

pi.ItemsPerPage = this.PageSize;

return PartialView("GetAdvData", new AdvsListViewModel { Advs=advs, PagingInfo=pi});

}

public ActionResult GetImg(string id)

{

//string path = (filename == null || filename == "") ? @"D:\ИИТ БГУИР\Курсач\MyRepetitor\MyRepetitor.WebUI\AdvPhotos\73\" + filename + ".jpg": (@"D:\ИИТ БГУИР\Курсач\MyRepetitor\MyRepetitor.WebUI\AdvPics\default.jpg");

if (id != null)

{

string[] strs = id.Split(new char[] { '-' });

if(strs.Length<2)

return Content("");

FileInfo file;

file = new FileInfo(Server.MapPath(String.Concat("~/AdvPhotos/",strs[0].Trim(),"/", strs[1], ".jpg").Trim()));

if (file.Exists)

return File(file.FullName, "text/plain", file.Name);

else return Content("");

}

else return Content("");

}

// JsonResults methods for ajax requests

public JsonResult GetAdvsJson(SearchInfo si)

{

var data = si.FilterAdvsWithoutPaging(advRepository.GetAll()).Select(a => new {

Title = a.Topic,

Link = Url.Action("Details", "Advertizements", new { id=a.AdvertizementId}),

Address = String.Concat(a.City??"", ", ", a.Adress??""),

Price=a.Price,

Owner=String.Concat(a.AdvertizementOwner.FirstName, " ", a.AdvertizementOwner.LastName),

OwnerLink = Url.Action("Details", "Account", new { id = a.AdvertizementOwnerId })

});

return Json(data, JsonRequestBehavior.AllowGet);

}

private SearchInfo FillSearchInfoByLists(SearchInfo searchInfo)

{

searchInfo.Categories = repository.AdvertizementCategories;

searchInfo.DogBreeds = repository.DogBreeds;

searchInfo.Cities = new string[] { "Минск" }.Concat(repository.Advertizements.Where(x=>x.City!=null).Select(x => x.City).OrderBy(x => x)).Distinct();

return searchInfo;

}

}

}

using MyPet.Domain.Abstract;

using MyPet.Domain.Entities;

using MyPet.WebUI.Models;


Подобные документы

  • Сравнение показателей ресурсов cenotavr.by и petonik.com. Редактирование объявлений, задание критериев отбора объявлений по фильтрам. Разработка проекта программного обеспечения для сайта услуг для животных, алгоритм редактирования и удаления питомца.

    дипломная работа [2,8 M], добавлен 09.07.2017

  • Цели и задачи фирм по обмену и продаже жилья, основные моменты работы фирмы для создания системы автоматизации учёта данных о заявках и клиентах. Функциональная модель приложения, разработка инфологической модели и создание реляционной структуры.

    курсовая работа [389,8 K], добавлен 20.03.2012

  • Программные средства, которые помогают манипулировать и управлять данными. Приемы создания и редактирования баз данных в СУБД MySQL. Способы и средства доступа и манипулирования данными. Создание, удаление, редактирование таблиц данных и их элементов.

    практическая работа [1,2 M], добавлен 14.03.2013

  • Анализ предметной области. Проектирование и разработка базы данных и интерфейса в виде набора Web-страниц для отображения, создания, удаления и редактирования записей базы данных. Аппаратное и программное обеспечение системы. Алгоритм работы программы.

    курсовая работа [3,0 M], добавлен 12.01.2016

  • Особенность формирования реляционной модели данных. Создание таблиц в программе. Характеристика разработки web-интерфейса. Анализ вывода информации о каждом сотруднике. Образование листинга программных кодов. Суть удаления и редактирования извещений.

    курсовая работа [621,5 K], добавлен 14.01.2018

  • Изучение областей использования вычислительной техники, истории систем управления данными во внешней памяти. Анализ разработки ряда стандартов в рамках языков описания и манипулирования данными. Обзор технологий по обмену данными между различными СУБД.

    презентация [263,2 K], добавлен 30.05.2012

  • Проектирование концептуальной, логической и физической модели базы данных. Формирование сущностей и связей между ними. Создание форм с функциями добавления, редактирования, удаления, поиска, печати. Разработка клиентской части БД с помощью среды Lazarus.

    курсовая работа [1,3 M], добавлен 05.04.2015

  • Разработка программного продукта - базы данных "Экскурсия" в интегрированной среде программирования C++ Builder 6. Определение порядка просмотра данных базы, их редактирования и удаления. Особенности руководства пользователя и общего интерфейса программы.

    курсовая работа [2,4 M], добавлен 03.11.2013

  • Средства организации блогов, разновидности CMS используемых для разработки и сопровождения блогов, их достоинства и недостатки. Общий алгоритм работы программного средства и алгоритмы работы с данными. Программное конструирование индивидуальных блогов.

    дипломная работа [3,6 M], добавлен 10.07.2012

  • Требования к аппаратным и операционным ресурсам. Логическая и физическая организация. Состав основных классов проекта. Технико-экономическое обоснование разработки программного средства. Задержки при обработке данных. Разработка интерфейса приложения.

    дипломная работа [4,4 M], добавлен 16.06.2017

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.