Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP.NET MVC Урок 1-F / ASP.NET MVC Урок 5

.pdf
Скачиваний:
46
Добавлен:
09.03.2016
Размер:
1.07 Mб
Скачать

$63 1(7 09& ǻȘȖȒ ǹȖȏȌȈȕȐȍ ȏȈȗȐșȐ Ȋ ǩǬtutorial

ASP*, .NET*

Цель урока. Отследить весь путь создания записи в БД и вывода его. Вывод ошибок. Валидация. Мапперы. Написание атрибута валидации. Капча. Создание данных в БД.

Введение

Наконец, переходим к одному из самых важных уроков, в котором будет рассказано про создание записей. Любое действие на сайте, от сложных, когда мы заполняем регистрационную анкету, до простых, когда ставим лайк, – происходит следующим образом:

Post\get запрос на сайт

Авторизация и аутентификация

Проверка введенных данных (валидация) на правильность

Если проверка введенных данных показала, что введенные данные неверны, то в заполняемую форму выводится предупреждение.

Если проверка введенных данных показала, что эти данные верны, то они сохраняются в БД и выводится страница с подтверждением.

Регистрация

Сделаем форму для регистрации пользователя. При регистрации, пользователь должен распознать капчу и повторить ввод пароля. Но начнем без этого. Создадим метод Register в

контроллере UserController и View.

SXEOLF $FWLRQ5HVXOW5HJLVWHU

^

YDUQHZ8VHU QHZ8VHU

UHWXUQ9LHZ QHZ8VHU

`

Создаем и передаем во View новый объект User. Так как полей у нас пока только два, для заполнения создаем View:

#XVLQJ +WPO %HJLQ)RUP 5HJLVWHU 8VHU )RUP0HWKRG 3RVW QHZ ^ #FODVV IRUP KRUL]RQWDO `

^

ILHOGVHW!

GLY FODVV FRQWURO JURXS!

ODEHO FODVV FRQWURO ODEHO IRU (PDLO!

(PDLO

ODEHO!

GLY FODVV FRQWUROV!

#+WPO 9DOLGDWLRQ0HVVDJH (PDLO

#+WPO 7H[W%R[ (PDLO 0RGHO (PDLO

GLY!

GLY!

GLY FODVV FRQWURO JURXS!

ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!

3DVVZRUG

ODEHO!

GLY FODVV FRQWUROV!

#+WPO 9DOLGDWLRQ0HVVDJH 3DVVZRUG

#+WPO 3DVVZRUG 3DVVZRUG 0RGHO 3DVVZRUG

GLY!

GLY!

GLY FODVV IRUP DFWLRQV!

EXWWRQ W\SH VXEPLW FODVV EWQ EWQ SULPDU\!

5HJLVWHU

EXWWRQ!

#+WPO$FWLRQ/LQN &DQFHO ,QGH[ QXOO QXOO QHZ ^ #FODVV EWQ `

GLY!

ILHOGVHW!

`

Все эти дивы, fieldset'ы и button’ы сделаны по подобию, как это описано в фреймворке bootstrap (далее будем изучать).

Изучим основные Html­вставки:

+WPO %HJLQ)RUP5HJLVWHU 8VHU)RUP0HWKRG 3RVWQHZ^ #FODVV IRUP KRUL]RQWDO`

— формирует тегIRUP DFWLRQ ´ 8VHU 5HJLVWHU´ PHWKRG ´SRVW´ FODVV ´IRUP KRUL]RQWDO´! и

закрывает его после вызова 'LVSRVH(закрытие кавычек XVLQJ ^`)

#+WPO 7H[W%R[(PDLO0RGHO (PDLO

— формирует тег LQSXW W\SH ´WH[W´ QDPH ´(PDLO´ YDOXH ´#0RGHO (PDLO´!(т.е. в значение тега записывается значение Email переданного объекта)

#+WPO 9DOLGDWLRQ0HVVDJH3DVVZRUG

— выводит тег ошибки если такая есть

#+WPO 3DVVZRUG3DVVZRUG0RGHO 3DVVZRUG

— выводит тегLQSXW W\SH ´SDVVZRUG´ QDPH ´3DVVZRUG´ YDOXH ´#0RGHO 3DVVZRUG´!

После нажатия на кнопку Register идет Http­запрос типа POST (так как)RUP0HWKRG 3RVW и

передает данные Email=&Password=.

Создадим метод Register, принимающий в качестве параметра тип User, и пометим его атрибутом HttpPost, а предыдущий — атрибутом HttpGet. Контроллер различает, какой из типов запроса сейчас происходит и перенаправляет на тот, который необходим:

>+WWS*HW@

SXEOLF $FWLRQ5HVXOW5HJLVWHU

^

YDUQHZ8VHU QHZ8VHU

UHWXUQ9LHZ QHZ8VHU

`

>+WWS3RVW@

SXEOLF $FWLRQ5HVXOW5HJLVWHU8VHU XVHU

^

UHWXUQ9LHZ XVHU

`

Сделаем точку останова на втором методе Register и проверим, какой объект приходит к нам:

Видим, что поля Email и Password заполнены, остальные остались нулевыми или по умолчанию

(default).

Так как мы должны принять еще 2 поля (повтор пароля и капчу), то добавим эти поля в наш User partial class:

SXEOLF SDUWLDO FODVV 8VHU

^

SXEOLF VWDWLF VWULQJ *HW$FWLYDWH8UO

^

UHWXUQ*XLG 1HZ*XLG 7R6WULQJ1

`

SXEOLF VWULQJ&RQILUP3DVVZRUG ^JHW VHW`

SXEOLF VWULQJ&DSWFKD ^JHW VHW`

`

Добавим поля во View:

GLY FODVV FRQWURO JURXS!

ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!

&RQILUP 3DVVZRUG

ODEHO!

GLY FODVV FRQWUROV!

#+WPO 9DOLGDWLRQ0HVVDJH &RQILUP3DVVZRUG

#+WPO 3DVVZRUG &RQILUP3DVVZRUG 0RGHO &RQILUP3DVVZRUG

GLY!

GLY!

GLY FODVV FRQWURO JURXS!

ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!

&DSWFKD

ODEHO!

GLY!

GLY FODVV FRQWURO JURXS!

ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!

Ɍɭɬ ɤɚɪɬɢɧɤɚ

ODEHO!

GLY FODVV FRQWUROV!

#+WPO 9DOLGDWLRQ0HVVDJH &DSWFKD

#+WPO 7H[W%R[ &DSWFKD 0RGHO &DSWFKD

GLY!

GLY!

Капчу пока не будем делать, просто она будет равна 1234.

Валидация

Условия для правильности данных:

Поле email не нулевое

Email – это корректно введенный адрес почты, т.е. с собачкой

Email добавляемый в БД — уникальный

Пароль не нулевой

Пароли совпадают Капча равна 1234

Если какое­то из этих условий не соблюдается, то выдается ошибка.

IValidatableObject

Так как у нас класс User — partial, то мы можем реализовать для него IValidatableObject интерфейс, для этого, правда, придется добавить в проект System.Component.DataAnnotation. Это не очень хорошо, так как эта сборка необходима для валидации, а валидация – это прерогатива контроллеров в MVC. Так что мы тут немного нарушаем принцип.

Класс User:

SXEOLF SDUWLDO FODVV 8VHU ,9DOLGDWDEOH2EMHFW

^

SXEOLF VWDWLF VWULQJ *HW$FWLYDWH8UO

^

UHWXUQ*XLG 1HZ*XLG 7R6WULQJ1

`

SXEOLF VWULQJ&RQILUP3DVVZRUG ^JHW VHW`

SXEOLF VWULQJ&DSWFKD ^JHW VHW`

SXEOLF,(QXPHUDEOH 9DOLGDWLRQ5HVXOW!9DOLGDWH9DOLGDWLRQ&RQWH[W YDOLGDWLRQ&RQWH[W

^

ɇɟ ɧɭɥɟɜɨɣ (PDLO

LI VWULQJ,V1XOO2U:KLWH6SDFH (PDLO

^

\LHOGUHWXUQ QHZ9DOLGDWLRQ5HVXOW ȼɜɟɞɢɬɟ HPDLOQHZVWULQJ>@ ^(PDLO`

`

ɤɨɪɪɟɤɬɧɵɣ (PDLO

YDUUHJH[ QHZ5HJH[# ?Z > @?Z #?Z > @?Z ? ?Z > @?Z5HJH[2SWLRQV & RPSLOHG

YDUPDWFK UHJH[ 0DWFK (PDLO

LIPDWFK 6XFFHVV PDWFK /HQJWK (PDLO /HQJWK

^

\LHOGUHWXUQ QHZ9DOLGDWLRQ5HVXOW ȼɜɟɞɢɬɟ ɤɨɪɪɟɤɬɧɵɣ HPDLOQHZVWULQJ>@ ^(PD LO`

`

ɩɚɪɨɥɶ ɧɟ ɧɭɥɟɜɨɣ

LI VWULQJ,V1XOO2U:KLWH6SDFH 3DVVZRUG

^

\LHOGUHWXUQ QHZ9DOLGDWLRQ5HVXOW ȼɜɟɞɢɬɟ ɩɚɪɨɥɶQHZVWULQJ>@ ^3DVVZRUG`

`

ɩɚɪɨɥɢ ɫɨɜɩɚɞɚɸɬ

LI3DVVZRUG &RQILUP3DVVZRUG

^

\LHOGUHWXUQ QHZ9DOLGDWLRQ5HVXOW ɉɚɪɨɥɢ ɧɟ ɫɨɜɩɚɞɚɸɬQHZVWULQJ>@ ^&RQILUP3

DVVZRUG`

`

`

`

Мы смогли сделать проверку 4 из 6 правил валидации, но оставим пока так, а остальные добавим непосредственно в контроллере.

Выполняем форму, получаем:

Видим, что обе наши ошибки были отловлены.

Есть два стандартных метода вывести ошибку: это Html.ValidationMessage(“ErrorField”) и Html.ValidationSummary(). Первый выводит ошибку, связанную с конкретным неверновведенным полем, а второе — выведет все (или все оставшиеся) ошибки.

Добавляем в контроллер проверку на капчу и проверку на существование Email в БД

(/Areas/Default/UserController.cs:Register):

LIXVHU &DSWFKD

^

0RGHO6WDWH$GG0RGHO(UURU&DSWFKD Ɍɟɤɫɬ ɫ ɤɚɪɬɢɧɤɢ ɜɜɟɞɟɧ ɧɟɜɟɪɧɨ

`

YDUDQ\8VHU 5HSRVLWRU\ 8VHUV$Q\ S !VWULQJ&RPSDUH S (PDLO XVHU (PDLO

LIDQ\8VHU

^

0RGHO6WDWH$GG0RGHO(UURU(PDLO ɉɨɥɶɡɨɜɚɬɟɥɶ ɫ ɬɚɤɢɦ HPDLO ɭɠɟ ɡɚɪɟɝɢɫɬɪɢɪɨɜɚɧ

`

И результат:

Что ж, с задачей мы справились, но в дальнейшем, используя такой способ, мы получим несколько проблем:

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

Валидацию мы сделали частично в Model­части и частично в Controller­части – это не совсем хрестоматийно.

Но есть решение, мы создаем класс, который является представлением класса User, организующим валидацию. Мы назовем его UserView и создадим в папке Models/ViewModels:

SXEOLF FODVV 8VHU9LHZ

^

SXEOLF LQW,' ^JHW VHW`

SXEOLF VWULQJ(PDLO ^JHW VHW`

SXEOLF VWULQJ3DVVZRUG ^JHW VHW`

SXEOLF VWULQJ&RQILUP3DVVZRUG ^JHW VHW`

SXEOLF VWULQJ&DSWFKD ^JHW VHW`

SXEOLF VWULQJ $YDWDU3DWK ^JHW VHW`

`

Automapping

Прежде чем приступить к использованию этого класса, стоит заметить, что это не совсем удобно. Мы создали совершенно другой класс, но добавлять в БД мы должны класс User, а это означает, что в каком­то месте программы мы должны передавать от объекта UserView в User поля, так и наоборот. А при большом количестве объектов и полей – это рутинно, к тому же, подобное у нас уже есть в функции Update[Table] в репозитории. Для решения этой задачи существуют так называемые мапперы object­to­object.

Одним из самых популярных, является automapper (http://automapper.org/). Собственно, эта библиотека берет на себя работу по переводу одного объекта в другой, и, как мы дальше увидим, там еще есть много других вкусных плюшек.

Устанавливаем Automapper:

,QVWDOO 3DFNDJH$XWR0DSSHU

Так как при разработке программы мы избегаем сильную связность, то организуем интерфейс + реализацию и зарегистрируем это в Ninject, после чего выведем использование в контроллер.

Создаем в /Mappers:

SXEOLF LQWHUIDFH ,0DSSHU

^

REMHFW 0DS REMHFWVRXUFH 7\SH VRXUFH7\SH 7\SH GHVWLQDWLRQ7\SH

`

Реализация:

SXEOLF FODVV &RPPRQ0DSSHU ,0DSSHU

^

VWDWLF &RPPRQ0DSSHU

^

0DSSHU &UHDWH0DS 8VHU 8VHU9LHZ!

0DSSHU &UHDWH0DS 8VHU9LHZ 8VHU!

`

SXEOLF REMHFW 0DS REMHFWVRXUFH 7\SH VRXUFH7\SH 7\SH GHVWLQDWLRQ7\SH

^

UHWXUQ0DSSHU 0DS VRXUFH VRXUFH7\SH GHVWLQDWLRQ7\SH

`

`

Регистрация (пусть будет как объект­одиночка) (/App_Start/NinjectWebCommon.cs):

NHUQHO %LQG ,0DSSHU! 7R &RPPRQ0DSSHU! ,Q6LQJOHWRQ6FRSH

В BaseController (/Controllers/BaseController.cs):

SXEOLF DEVWUDFW FODVV %DVH&RQWUROOHU &RQWUROOHU

^

>,QMHFW@

SXEOLF,5HSRVLWRU\ 5HSRVLWRU\ ^JHW VHW`

>,QMHFW@

SXEOLF,0DSSHU 0RGHO0DSSHU ^JHW VHW`

`

Теперь изменим UserController (и View) с использованием UserView:

>+WWS*HW@

SXEOLF $FWLRQ5HVXOW5HJLVWHU

^

YDUQHZ8VHU9LHZ QHZ8VHU9LHZ

UHWXUQ9LHZ QHZ8VHU9LHZ

`

>+WWS3RVW@

SXEOLF $FWLRQ5HVXOW5HJLVWHU8VHU9LHZ XVHU9LHZ

^

LIXVHU9LHZ &DSWFKD

^

0RGHO6WDWH$GG0RGHO(UURU&DSWFKD Ɍɟɤɫɬ ɫ ɤɚɪɬɢɧɤɢ ɜɜɟɞɟɧ ɧɟɜɟɪɧɨ

`

YDUDQ\8VHU 5HSRVLWRU\ 8VHUV$Q\ S !VWULQJ&RPSDUH S (PDLO XVHU9LHZ (PDLO

LIDQ\8VHU

^

0RGHO6WDWH$GG0RGHO(UURU(PDLO ɉɨɥɶɡɨɜɚɬɟɥɶ ɫ ɬɚɤɢɦ HPDLO ɭɠɟ ɡɚɪɟɝɢɫɬɪɢɪɨɜɚ ɧ

`

LI0RGHO6WDWH ,V9DOLG

^

YDUXVHU 8VHU 0RGHO0DSSHU 0DS XVHU9LHZW\SHRI8VHU9LHZW\SHRI8VHU

72'2 ɋɨɯɪɚɧɢɬɶ

`

UHWXUQ9LHZ XVHU9LHZ

`

И в Register.cshtml изменится первая строка:

#PRGHO /HVVRQ3URMHFW 0RGHOV 9LHZ0RGHOV 8VHU9LHZ

Атрибуты

Для UserView будем использовать для валидации атрибуты.

Добавим сборку:

XVLQJ6\VWHP &RPSRQHQW0RGHO 'DWD$QQRWDWLRQV SXEOLF FODVV 8VHU9LHZ

^

SXEOLF LQW,' ^JHW VHW`

>5HTXLUHG (UURU0HVVDJH ȼɜɟɞɢɬɟ HPDLO@

SXEOLF VWULQJ(PDLO ^JHW VHW`

>5HTXLUHG (UURU0HVVDJH ȼɜɟɞɢɬɟ ɩɚɪɨɥɶ@

SXEOLF VWULQJ3DVVZRUG ^JHW VHW`

>&RPSDUH3DVVZRUG(UURU0HVVDJH ɉɚɪɨɥɢ ɞɨɥɠɧɵ ɫɨɜɩɚɞɚɬɶ@

SXEOLF VWULQJ&RQILUP3DVVZRUG ^JHW VHW`

SXEOLF VWULQJ&DSWFKD ^JHW VHW`

SXEOLF VWULQJ $YDWDU3DWK ^JHW VHW`

`

Проверяем:

Соседние файлы в папке ASP.NET MVC Урок 1-F