Маршрутизация ASP.net - использование запросов к базе данных для определения физического файла и добавления дополнительных данных маршрута из результатов запроса.

Мой вопрос касается маршрутизации страниц на веб-сайте веб-форм ASP.net (VB).

Мне нужно перейти на 2 страницы .aspx несколькими способами, например.

routes.MapPageRoute("SEO", "{Title}/{Id}", "~/PageA.aspx")
routes.MapPageRoute("Catalogue", "Issue{IssueNumber}-{PageNumber}", "~/PageA.aspx")

но мне нужно реализовать некоторую логику, включающую запросы к базе данных (LINQ to SQL) на обоих маршрутах, например.

Маршрут 1) Проверить битовое поле, если false, то физический файл = PageA.aspx, true то PageB.aspx

Маршрут 2) Поиск IssueNumber и PageNumber, получение PageId и добавление в RouteData, установка физического файла = PageA.aspx

Я думаю, что лучший способ сделать это - реализовать класс IRouteHandler, но я не смог определить:

  • Куда писать запросы к базе данных в таком классе
  • Как установить физический файл в классе
  • Где / как добавить новое значение в данные маршрута, например, PageId
  • Где проверить, что поля Id и Number на самом деле являются целыми числами (ограничения?)

Я не могу найти полезной документации VB.net, есть предложения?

Если нет, мне придется прибегнуть к промежуточной странице .aspx, то есть Transfer.aspx, а затем выполнить запросы к базе данных, а затем сохранить возвращаемые значения в переменных сеанса, а затем выполнить Server.Transfer(PageA.aspx), но это похоже на старомодный и неэлегантный способ сделать это. Пожалуйста помоги!


person Chris Cannon    schedule 23.02.2012    source источник


Ответы (1)


Вместо того, чтобы писать свой собственный IRouteHandler, я бы предложил реализовать свой класс Route. Переопределите GetRouteData и настройте возвращаемый объект RouteData в соответствии с вашими потребностями.

Куда писать запросы к базе данных в таком классе

Как упоминалось выше, GetRouteData - это то место, которое вы ищете.

Как установить физический файл в классе

В возвращаемом объекте RouteData установите RouteHandler на новый экземпляр PageRouteHandler. Вы можете передать физический путь конструктору PageRouteHandler.

Где / как добавить новое значение в данные маршрута, например, PageId

Используйте свойство Values ​​объекта RouteData.

Где проверить, что поля Id и Number на самом деле являются целыми числами (ограничения?)

Это должно быть сделано с ограничениями маршрута. Шестым параметром MapPageRoute, например, является RouteValueDictionary с ограничениями. Чтобы просто проверить, является ли параметр целым числом, используйте регулярное выражение, например:

routes.MapPageRoute("RouteName", _
  "product/{id}", "~/Products.aspx", _
  True, New RouteValueDictionary(), _
  New RouteValueDictionary() From { {"id", "\d+"} })

Видите "\ d +" в конце? Это регулярное выражение, которому должен соответствовать параметр id.

Если вам нужны более сложные ограничения, вы также можете сделать это, см., Например, http://stephenwalther.com/blog/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

person Andre Loker    schedule 24.02.2012
comment
Спасибо, я никогда не думал об этом так. Итак, все, что мне нужно сделать, это реализовать свой собственный класс маршрутизации по наследству? а затем переопределить соответствующие члены? - person Chris Cannon; 24.02.2012
comment
Значит ли это, что объекты маршрута создаются каждый раз, когда пользователь обращается к другой странице? - person Chris Cannon; 24.02.2012
comment
Объекты Route добавляются в RouteCollection только один раз (обычно во время Application_Start), но для каждого запроса создается объект RouteData. - person Andre Loker; 24.02.2012
comment
Я думаю, проблема в том, что RouteData не позволяет вам устанавливать значения, которые доступны только для чтения. Я думал о сохранении PageId в DataToken, но я почти уверен, что, поскольку объекты Route устанавливаются во время Application_Start, они не будут меняться от страницы к странице. - person Chris Cannon; 24.02.2012
comment
Вы не можете установить свойство Values, это правда. Но вы можете изменить его содержимое, например routeData.Values.Add (PageId, myPageId) и т. Д. И, как я уже сказал, объект Route не изменится, но создаваемый вами объект RouteData является новым для каждого запроса. - person Andre Loker; 24.02.2012
comment
Так вызывается ли метод GetRouteData автоматически при каждом запросе? - person Chris Cannon; 25.02.2012
comment
да. Он вызывается на каждом маршруте вплоть до первого маршрута, который не возвращает null. Вот быстрый пример того, как реализовать то, что я имею в виду (этот обрабатывает маршрут Проблема {IssueNumber} - {PageNumber}): gist.github.com/1903446 Вы также можете переопределить GetVirtualPath, если хотите охватить противоположный случай (создать URL-адрес из данных маршрута). - person Andre Loker; 25.02.2012
comment
О, я забыл показать, как им пользоваться: gist.github.com/1903507. Первый параметр - это маршрут для сопоставления, второй определяет значения по умолчанию, а третий - ограничения. - person Andre Loker; 25.02.2012
comment
Вау, это фантастика, большое спасибо ... Я был совершенно на неправильном пути с IRouteHandler - я виню документацию MSDN, как грязь. Спасибо за код, во время этих комментариев я читал документацию MSDN по классу Route, и все постепенно становилось на свои места, но, честно говоря, я не думаю, что смог бы реализовать это без вашего кода. Спасибо. :) - person Chris Cannon; 25.02.2012
comment
Хе-хе, пожалуйста. Я случайно реализовал свои собственные маршруты для CMS, над которой работаю на днях, так что я все еще был занят этой темой. - person Andre Loker; 25.02.2012