ASP.NET MVC Урок 1-F / ASP.NET MVC Урок 4
.pdf$63 1(7 09& ǻȘȖȒ 5RXWLQJ tutorial
ASP*, .NET*
Цель урока: Изучить инициализацию маршрутизации. Деление на Areas в приложении. Принципы создания маршрутизации.
Controller и Action.
Вебсайт состоит из страниц. Вообще, вебсайт состоит не из страниц, а из ответов на запросы, но какуюто определенную структуру мы хотим иметь.
Собственно, у нас есть маршрутизатор, который должен определить, какой метод у какого контроллера вызвать. Поэтому, два основных параметра, которые обязательно должны быть это controller и action. Рассмотрим как задается шаблон маршрутов в App_Start/RouteConfig.cs:
URXWHV 0DS5RXWH
QDPH'HIDXOW
XUO^FRQWUROOHU` ^DFWLRQ` ^LG`
GHIDXOWVQHZ^ FRQWUROOHU +RPHDFWLRQ ,QGH[LG 8UO3DUDPHWHU 2SWLRQDO
`
Таким образом,XUO © 5ROH &UHDWH ª будет означать, что мы находим
контроллер RoleController, в этом контроллере находим Create метод, который может принимать (а может и не принимать) параметр id. И если он принимает параметр id, то id = 2 или даже id = “2”, в зависимости, что за тип будет.
Defaults обозначает, что если строка будет “/Role/Create” – то в случае, что Create метод с параметром id и по умолчанию не стоит значение, или не может быть создано default(), то по возможности будет выбран другой метод (мы же полиморфны). Иначе будет сгенерирована ошибка: не найден метод, готовый принять такой запрос.
SXEOLF $FWLRQ5HVXOW,QGH[ LQW" LG
^
RN
UHWXUQ9LHZ
`
«
SXEOLF $FWLRQ5HVXOW,QGH[ LQWLG
^
RN
UHWXUQ9LHZ
`
«
SXEOLF $FWLRQ5HVXOW,QGH[ LQWLG
^
IDLO
UHWXUQ9LHZ
`
Вслучае url = “/Role” будет вызван метод Index в контроллере RoleController.
Вслучае url = “/” будет вызван метод Index в контроллере HomeController.
Рассмотрим на примерах.
BaseController
Создадим несколько контроллеров, но для того, чтобы не создавать постоянно доступ к репозиторию, первоначально создадим базовый контроллер BaseController:
SXEOLF DEVWUDFW FODVV %DVH&RQWUROOHU &RQWUROOHU
^
>,QMHFW@
SXEOLF,5HSRVLWRU\ 5HSRVLWRU\ ^JHW VHW`
`
И
SXEOLF FODVV +RPH&RQWUROOHU %DVH&RQWUROOHU
^
SXEOLF $FWLRQ5HVXOW,QGH[
^
UHWXUQ9LHZ
`
`
View Home/Index.cshtml:
#^
9LHZ%DJ 7LWOH /HVVRQ3URMHFW
/D\RXW a 9LHZV 6KDUHG B/D\RXW FVKWPO
`
K!/HVVRQ3URMHFWK!
S!
GLY FODVV PHQX!
D KUHI #8UO$FWLRQ ,QGH[ 5ROH!ɊɨɥɢD!
#+WPO$FWLRQ/LQN ɉɨɥɶɡɨɜɚɬɟɥɢ ,QGH[ 8VHU
GLY!
S!
Добавим для просмотра RoleController:
SXEOLF FODVV 5ROH&RQWUROOHU %DVH&RQWUROOHU
^
SXEOLF $FWLRQ5HVXOW,QGH[
^
YDUUROHV 5HSRVLWRU\ 5ROHV 7R/LVW
UHWXUQ9LHZ UROHV
`
`
И
#PRGHO ,/LVW/HVVRQ3URMHFW 0RGHO 5ROH!
#^
9LHZ%DJ 7LWOH 5ROHV
/D\RXW a 9LHZV 6KDUHG B/D\RXW FVKWPO
`
K!5ROHVK!
S!
#IRUHDFK YDU UROH LQ 0RGHO
^
GLY FODVV LWHP!
VSDQ FODVV LG!
#UROH ,'
VSDQ!
VSDQ FODVV QDPH!
#UROH 1DPH
VSDQ!
VSDQ FODVV &RGH!
#UROH &RGH
VSDQ!
GLY!
`
S!
И такой же UserController, собственно, сделаем.
Рассмотрим, как задаются маршруты с помощью Url.Action() и Html.ActionLink().
Url.Action() – принимает параметры, первым – action, потом – controller, потом через new {} – можно задавать и перечислять все остальные.
Html.ActionLink() – формирует тег D!, первый параметр – наименование ссылки, второй – action, третий – controller, четвертым(или пятым) параметром идут другие атрибуты тега, если мы хотим добавить другие параметры для маршрутизации – мы должны явно указать пятым параметром null. Т.е.:
#+WPO$FWLRQ/LQN ³ɉɨɥɶɡɨɜɚɬɟɥɶ ɩɨɞ ɧɨɦɟɪɨɦ ´ ³,WHP´ ³8VHU´ QHZ ^LG ` E!QXOO E!
Если не указать null:
#+WPO$FWLRQ/LQN ³ɉɨɥɶɡɨɜɚɬɟɥɶ ɩɨɞ ɧɨɦɟɪɨɦ ´ ³,WHP´ ³8VHU´ QHZ ^LG `
то ссылка будет выглядеть так:
D KUHI ´ 8VHU ,WHP"OHQJWK ´!ɉɨɥɶɡɨɜɚɬɟɥɶ ɩɨɞ ɧɨɦɟɪɨɦ D!
Порядок объявления маршрутов
Создадим маршрут, который будет расположен ранее и относится только к RoleController:
URXWHV 0DS5RXWH
QDPH5ROH
XUOUROL ^DFWLRQ` ^LG`
GHIDXOWVQHZ^ FRQWUROOHU 5ROHDFWLRQ ,QGH[LG 8UO3DUDPHWHU 2SWLRQDO
`
Строка “roli/{action}/{id}” однозначно задает имя контроллера в секции defaults. А action является параметром.
Результат. Ссылка стала:
D KUHI UROL !Ɋɨɥɢ D!
Уберем из defaults action=”Index”:
D KUHI UROL ,QGH[ !Ɋɨɥɢ D!
Поместим после объявления “Defaults”:
D KUHI 5ROH !Ɋɨɥɢ D!
Такая ссылка получилась, потому что вышестоящим правилом маршрута “default” можно задать путь к Role/Index:
FRQWH[W 0DS5RXWH
QDPHGHIDXOW
XUO^FRQWUROOHU` ^DFWLRQ` ^LG`
GHIDXOWVQHZ^ FRQWUROOHU +RPHDFWLRQ ,QGH[LG 8UO3DUDPHWHU 2SWLRQD
O `
Еще надо рассмотреть один метод, который называется ,JQRUH5RXWH, он указывает
маршрутизатору, что если url подходит под шаблон, то нужно вернуть ресурс, который расположен по тому адресу, а не пытаться находить контроллер.
Ограничения (Constrains)
Мы можем добавить в маршрутизацию ограничения запросов браузера, которые соответствуют особому маршруту. Например, id должен быть в нашем случае числовым:
URXWHV 0DS5RXWH
QDPH5ROH
XUOUROL ^DFWLRQ` ^LG`
GHIDXOWVQHZ^ FRQWUROOHU 5ROHDFWLRQ ,QGH[LG 8UO3DUDPHWHU 2SWLRQDO
`
FRQVWUDLQWVQHZ^LG # ?G`
При передаче id, которое не соответствует данному условию, будет или выбран другой маршрут, или метод не будет найден и ссылка будет битой:
Для:
D KUHI #8UO$FWLRQ ,QGH[ 5ROH QHZ ^ LG SULYHW ` !Ɋɨɥɢ D!
Будет:
D KUHI 5ROH ,QGH[ SULYHW !Ɋɨɥɢ D!
А для:
D KUHI #8UO$FWLRQ ,QGH[ 5ROH QHZ ^ LG ` !Ɋɨɥɢ D!
Будет:
D KUHI UROL ,QGH[ !Ɋɨɥɢ D!
Примечание: Более подробно об ограничениях можно узнать тут:http://stephenwalther.com/archive/2008/08/07/aspnetmvctip30createcustomroute constraints.aspx
Areas
Чтобы разделить различные по свойствам функциональные модули вебприложения. Например, форум отдельно от всего сайта. Мы же поделим на часть Admin – где будет админка, и всё остальное, которое будет называться Default.
Сделаем следующие действия:
Переименуем _Default в Default везде.
Перенесем свои контроллеры (кроме %DVH&RQWUROOHU) в папку Areas/Default/Controllers
Переименуем namespace для контроллеров в/HVVRQ3URMHFW$UHDV 'HIDXOW &RQWUROOHUV Исправляем 'HIDXOW$UHD5HJLVWUDWLRQ.
Здесь важно обратить внимание на новый параметр для задания маршрутов: namespaces, он указывает, из каких namespace можно выбирать контроллеры для разбора маршрута:
SXEOLF FODVV 'HIDXOW$UHD5HJLVWUDWLRQ $UHD5HJLVWUDWLRQ
^
SXEOLF RYHUULGH VWULQJ $UHD1DPH
^
JHW
^
UHWXUQ 'HIDXOW
`
`
SXEOLF RYHUULGH YRLG 5HJLVWHU$UHD $UHD5HJLVWUDWLRQ&RQWH[W FRQWH[W
^
FRQWH[W 0DS5RXWH
QDPHGHIDXOW
XUO^FRQWUROOHU` ^DFWLRQ` ^LG`
GHIDXOWVQHZ^ FRQWUROOHU +RPHDFWLRQ ,QGH[LG 8UO3DUDPHWHU 2 SWLRQDO `
QDPHVSDFHVQHZ>@ ^/HVVRQ3URMHFW$UHDV 'HIDXOW &RQWUROOHUV`
`
`
В Global.asax есть строка $UHD5HJLVWUDWLRQ 5HJLVWHU$OO$UHDVкоторая регистрирует все найденные объявления area, но она нам не подходит, так как если DefaultArea зарегистрировать раньше AdminArea, то будет срабатывать маршрутизация Default, а в админку мы уже не сможем попасть, поэтому исправляем:
YDUDGPLQ$UHD QHZ $GPLQ$UHD5HJLVWUDWLRQ
YDUDGPLQ$UHD&RQWH[W QHZ $UHD5HJLVWUDWLRQ&RQWH[W DGPLQ$UHD$UHD1DPH 5RXWH7DE OH 5RXWHV
DGPLQ$UHD 5HJLVWHU$UHD DGPLQ$UHD&RQWH[W
YDUGHIDXOW$UHD QHZ'HIDXOW$UHD5HJLVWUDWLRQ
YDUGHIDXOW$UHD&RQWH[W QHZ $UHD5HJLVWUDWLRQ&RQWH[W GHIDXOW$UHD$UHD1DPH 5RXW H7DEOH 5RXWHV
GHIDXOW$UHD 5HJLVWHU$UHD GHIDXOW$UHD&RQWH[W
Регистрацию маршрутов убираем (не api).
Запускаем.
Все исходники находятся по адресу https://bitbucket.org/chernikov/lessons