ASP.NET MVC Урок 1-F / ASP.NET MVC Урок 5
.pdfМы смогли описать тут 5 из 6 правил валидации. Правила, касающегося верного введенного email – нет. Напишем для этого свой классатрибут, проверяющий корректность введенного email:
>$WWULEXWH8VDJH$WWULEXWH7DUJHWV 3URSHUW\$OORZ0XOWLSOH IDOVH@
SXEOLF FODVV 9DOLG(PDLO$WWULEXWH 9DOLGDWLRQ$WWULEXWH
^
SXEOLF RYHUULGH ERRO ,V9DOLG REMHFW YDOXH
^
LI YDOXH QXOO
^
UHWXUQ WUXH
`
LI YDOXH LV VWULQJ
^
UHWXUQ WUXH
`
YDUVRXUFH YDOXH DV VWULQJ
LI VWULQJ,V1XOO2U:KLWH6SDFH VRXUFH
^
UHWXUQ WUXH
`
YDUUHJH[ QHZ5HJH[# ?Z > @?Z #?Z > @?Z ? ?Z > @?Z5HJH[2SWLRQV & RPSLOHG
YDUPDWFK UHJH[ 0DWFK VRXUFH
UHWXUQPDWFK 6XFFHVV PDWFK /HQJWK VRXUFH /HQJWK
`
`
Вначале проверяем, что полученный объект есть строка, и строка не пустая, иначе возвращаем значение «истина» в проверке. Тут срабатывает правило, что «мы у инопланетян документы не проверяем», т.е. пока нет достаточных условий для проверки – мы не проверяем, а проверять будут другие атрибуты. Потом же, с помощью регулярного выражения, проверяем. При желании, в интернете можно найти более полную проверку регулярным выражением с использованием всех доменов первого уровня.
Примечание: Можно подключить DataAnnotationsExtensions, чтобы не писать самому нужные атрибуты (http://dataannotationsextensions.org/)
Добавим пользователю поле дня рождения. Да, прямо сейчас, и посмотрим, как можно реализовать выбор даты.
1.Добавляем поле в БД. Birthdate datetime null.
Примечание: возможно, надо будет снять эту галочку, чтобы спокойно изменять структуру БД:
2.В данных выставим всем записям значения 201211
3.Изменим поле Birthdate на datetime not null
4.Удаляем из/HVVRQ3URMHFW'E GEPO таблицу User и заново переносим из Server Explorer
5.В SqlRepository/User.cs добавляем строку в UpdateUser():
SXEOLF ERRO 8SGDWH8VHU8VHU LQVWDQFH
^
8VHU FDFKH 'E 8VHUV :KHUH S ! S ,' LQVWDQFH ,' )LUVW2U'HIDXOW
LIFDFKH QXOO
^
FDFKH %LUWKGDWH LQVWDQFH %LUWKGDWH
FDFKH$YDWDU3DWK LQVWDQFH$YDWDU3DWK
FDFKH (PDLO LQVWDQFH (PDLO
'E 8VHUV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
6.В UserView у нас будет совершенно другое представление о поле Bithdate. И об этом чуть подробнее отдельно.
Выбор дня рождения у нас будет таким:
Тут надо решить несколько задач. Первая из них – создание и организация выпадающего списока. В Html (который мы еще позже рассмотрим подробнее) есть DropDownList, который реализует выпадающий список.
Параметры такие:
#+WPO 'URS'RZQ/LVW VWULQJ QDPH ,(QXPHUDEOH 6HOHFW/LVW,WHP! VHOHFW/LVW
Смотрим SelectListItem:
SXEOLF FODVV 6HOHFW/LVW,WHP
^
SXEOLF 6HOHFW/LVW,WHP
SXEOLF ERRO6HOHFWHG ^JHW VHW`
SXEOLF VWULQJ7H[W ^JHW VHW`
SXEOLF VWULQJ9DOXH ^JHW VHW`
`
Для выбора, например, из 1 — apple, 2 – orange (выбран), 3 — banana мы должны написать следующий код:
SXEOLF,(QXPHUDEOH 6HOHFW/LVW,WHP! 6HOHFW)UXLW
^
JHW
^
\LHOGUHWXUQ QHZ6HOHFW/LVW,WHP^ 9DOXH 7H[W DSSOH6HOHFWHG IDOVH`
\LHOGUHWXUQ QHZ6HOHFW/LVW,WHP^ 9DOXH 7H[W RUDQJH6HOHFWHG WUXH`
\LHOGUHWXUQ QHZ6HOHFW/LVW,WHP^ 9DOXH 7H[W EDQDQD6HOHFWHG IDOVH`
`
`
И передать в 'URS'RZQ/LVW вторым параметром, первый параметр – name, которому присвоится значение Value при подтверждении (сабмите) формы.
Cоздадим реализацию для выбора дня рождения:
SXEOLF LQW%LUWKGDWH'D\ ^JHW VHW`
SXEOLF LQW%LUWKGDWH0RQWK ^JHW VHW`
SXEOLF LQW%LUWKGDWH<HDU ^JHW VHW`
SXEOLF,(QXPHUDEOH 6HOHFW/LVW,WHP! %LUWKGDWH'D\6HOHFW/LVW
^
JHW
^
IRU LQWL L L
^
\LHOG UHWXUQ QHZ6HOHFW/LVW,WHP
^
9DOXH L 7R6WULQJ
7H[W L 7R6WULQJ
6HOHFWHG %LUWKGDWH'D\ L
`
`
`
`
SXEOLF,(QXPHUDEOH 6HOHFW/LVW,WHP! %LUWKGDWH0RQWK6HOHFW/LVW
^
JHW
^
IRU LQWL L L
^
\LHOG UHWXUQ QHZ6HOHFW/LVW,WHP
^
9DOXH L 7R6WULQJ
7H[W QHZ'DWH7LPH L 7R6WULQJ0000
6HOHFWHG %LUWKGDWH0RQWK L
`
`
`
`
SXEOLF,(QXPHUDEOH 6HOHFW/LVW,WHP! %LUWKGDWH<HDU6HOHFW/LVW
^
JHW
^
IRU LQWL L 'DWH7LPH 1RZ <HDU L
^
\LHOG UHWXUQ QHZ6HOHFW/LVW,WHP
^
9DOXH L 7R6WULQJ
7H[W L 7R6WULQJ
6HOHFWHG %LUWKGDWH<HDU L
`
`
`
`
И во View:
GLY FODVV FRQWURO JURXS!
ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!
%LUWK GDWH
ODEHO!
GLY FODVV FRQWUROV!
#+WPO 'URS'RZQ/LVW %LUWKGDWH'D\ 0RGHO %LUWKGDWH'D\6HOHFW/LVW
#+WPO 'URS'RZQ/LVW %LUWKGDWH0RQWK 0RGHO %LUWKGDWH0RQWK6HOHFW/LVW
#+WPO 'URS'RZQ/LVW %LUWKGDWH<HDU 0RGHO %LUWKGDWH<HDU6HOHFW/LVW
GLY!
GLY!
Запустим приложение и поставим брейкпоинт point на приеме данных. Проверим, как мы получаем данные для полей даты рождения для объекта UserView:
Теперь осталось правильно передать их в объект User. Опишем эту передачу в описании маппинга (/Mappers/CommonMapper.cs):
0DSSHU &UHDWH0DS 8VHU 8VHU9LHZ!
)RU0HPEHU GHVW ! GHVW %LUWKGDWH'D\ RSW ! RSW 0DS)URP VUF ! VUF %LUWKGDWH 'D\ )RU0HPEHU GHVW ! GHVW %LUWKGDWH0RQWK RSW ! RSW 0DS)URP VUF ! VUF %LUWKGDWH 0RQWK )RU0HPEHU GHVW ! GHVW %LUWKGDWH<HDU RSW ! RSW 0DS)URP VUF !VUF %LUWKGDWH <HDU
0DSSHU &UHDWH0DS 8VHU9LHZ 8VHU!
)RU0HPEHU GHVW ! GHVW %LUWKGDWH RSW ! RSW 0DS)URP VUF !QHZ'DWH7LPH VU
F %LUWKGDWH<HDU VUF %LUWKGDWH0RQWK VUF %LUWKGDWH'D\
Здесь мы задаем правила однозначного перевода из свойств BirthdateDay, BirthdateMonth, BirthdateYear в Birthdate и обратно.
Captcha
Для создания капчи, мы используем отдельный класс, который создаст нам картинку с цифрами и выведет как картинку. Сами цифры будут сохранены в сессионные данные. Про сессию мы дальше еще поговорим. Сейчас надо знать только, что сессия однозначно определяет пользователя.
Создадим Tools/CaptchaImage.cs:
Суть такова, что в свойство Image генерируется картинка, состоящая из цифр (которые как бы сложно распознать) методом GenerateImage().
Теперь сделаем метод вывода UserController.Captcha():
SXEOLF $FWLRQ5HVXOW&DSWFKD
^
6HVVLRQ>&DSWFKD,PDJH &DSWFKD9DOXH.H\@ QHZ5DQGRP 'DWH7LPH 1RZ 0LOOLVHFRQG 1H[W
7R6WULQJ
YDUFL QHZ&DSWFKD,PDJH 6HVVLRQ>&DSWFKD,PDJH &DSWFKD9DOXH.H\@ 7R6WULQJ$ULDO
&KDQJH WKH UHVSRQVH KHDGHUV WR RXWSXW D-3(* LPDJH
WKLV5HVSRQVH &OHDU
WKLV5HVSRQVH &RQWHQW7\SH LPDJH MSHJ
:ULWH WKH LPDJH WR WKH UHVSRQVH VWUHDP LQ-3(* IRUPDW
FL ,PDJH 6DYHWKLV5HVSRQVH 2XWSXW6WUHDP ,PDJH)RUPDW-SHJ
'LVSRVH RI WKH &$37&+$LPDJH REMHFW
FL 'LVSRVH
UHWXUQ QXOO
`
Что здесь происходит:
В сессии создаем случайное число от 1111 до 9999.
Создаем в ci объект CatchaImage
Очищаем поток вывода
Задаем header для mimeтипа этого httpответа будет “image/jpeg” т.е. картинка формата jpeg.
Сохраняем bitmap в выходной поток с форматом ImageFormat.Jpeg Освобождаем ресурсы Bitmap
Возвращаем null, так как основная информация уже передана в поток вывода
Запрашиваем картинку из Register.cshtml (/Areas/Default/View/User/Register.cshtml):
ODEHO FODVV FRQWURO ODEHO IRU )LUVW1DPH!
LPJ VUF #8UO$FWLRQ &DSWFKD 8VHU DOW FDSWFKD!
ODEHO!
Проверка (/Areas/Default/Controllers/UserController.cs):
LIXVHU9LHZ &DSWFKD VWULQJ6HVVLRQ>&DSWFKD,PDJH &DSWFKD9DOXH.H\@
^
0RGHO6WDWH$GG0RGHO(UURU&DSWFKD Ɍɟɤɫɬ ɫ ɤɚɪɬɢɧɤɢ ɜɜɟɞɟɧ ɧɟɜɟɪɧɨ
`
Вот и всё, закончили. Добавляем создание записи и проверяем, как она работает:
LI0RGHO6WDWH ,V9DOLG
^
YDUXVHU 8VHU 0RGHO0DSSHU 0DS XVHU9LHZW\SHRI8VHU9LHZW\SHRI8VHU
5HSRVLWRU\ &UHDWH8VHU XVHU UHWXUQ5HGLUHFW7R$FWLRQ,QGH[
`
Все исходники находятся по адресу https://bitbucket.org/chernikov/lessons