ASP.NET: тонкости работы с контролом CascadingDrowDown

30 ноября 2008, 12:43
Пример работы CascadingDropDown
Пример работы CascadingDropDown
Контрол CascadingDropDown, входящий в состав ASP.NET Ajax Control Toolkit, служит для создания нескольких зависимых друг от друга выпадающих списков (DropDownList-ов) — например, в первом выбирается страна, во втором после выбора страны загружается список городов выбранной страны и так далее. Очень удобный контрол, позволяет работать как с данными из БД, так и с данными из xml-файлов.

И вот буквально сегодня я столкнулся с одной проблемой. Рассказываю, в чём она заключалась и как я её решил.

В чём проблема?
В одном из своих проектов я использую user-friendly URL's. Для этого я подключаю к проекту UrlRewriting.NET — компонент для rewrite адресов в ASP.NET-сайте. Кстати, весьма удобная вещь, рекомендую к использованию.
Так вот, страница регистрации физически находится по адресу вроде /system/signup.aspx, но все ссылки на сайте ведут на /signup/ — для большей красоты :) И вот на этой странице перестал работать CascadingDropDown. Выдаёт ошибку «Error method 500» — и всё.

Как я искал проблему
Покопался я немного в коде и после нескольких экспериментов установил, что если страница после реврайта (скрытой переадресации) находится по адресу /signup.aspx или /signup/default.aspx, то CascadingDropDown работает. Если по адресу вроде /signup/a — тоже работает. То есть если страница находится не по адресу /signup/, а заканчивается на имя какого-то файла, то CascadingDropDown работает.

Тогда я додумался поглядеть уже сгенерированный код html-страницы — и быстро понял, в чем проблема. Посмотрите, вот это ASP.NET код на странице signup.aspx:
<asp:DropDownList ID="CountryLives" runat="server" Width="252px" CssClass="inputfield"></asp:DropDownList><br />
<cc1:CascadingDropDown ID="CascadingDropDown2" runat="server"
TargetControlID="CountryLives"
Category="Live"
PromptText="[выберите область]"
LoadingText="[загрузка списка областей]"
ServicePath="~/WebServices/GetLocation.asmx"
ServiceMethod="GetLives"
ParentControlID="Country">
</cc1:CascadingDropDown>

А вот что генерируется в конце концов в html-коде (при загрузке страницы по адресу /signup/):
Sys.Application.add_init(function() {
$create(AjaxControlToolkit.CascadingDropDownBehavior, {"Category": "Live", "ClientStateFieldID": "ctl00_ContentPage_CascadingDropDown2_ClientState", "LoadingText": "[загрузка списка областей]", "ParentControlID": "ctl00_ContentPage_Country", "PromptText": "[выберите область]", "ServiceMethod": "GetLives", "ServicePath": "WebServices/GetLocation.asmx", "id": "ctl00_ContentPage_CascadingDropDown2"}, null, null, $get("ctl00_ContentPage_CountryLives"));
});

Как видно, я ASP.NET-контроле я прописываю ServicePath от корня приложения: ~/WebServices/GetLocation.asmx. В JavaScript-е в генерируемой html-страницеServicePath прописывается как WebServices/GetLocation.asmx – то есть не от корня сайта, а от текущего каталога. То есть определяется неправильно.

Если же адрес страницы заканчивается каким-то файлом (/signup/default.aspx – к примеру), то в JavaScript-е ServicePath имеет значение "../WebServices/GetLocation.asmx". То есть в этом случае определяется правильно.

Итак, как решить проблему?
Теперь, используя результат этих наблюдений, это совсем несложно: просто в ASP.NET коде устанавливаем значение ServicePath не “~/WebServices/GetLocation.asmx”, а “/WebServices/GetLocation.asmx” – принудительно от корня приложения. В таком случае в JavaScript значение параметра ServicePath тоже прописывается как “/WebServices/GetLocation.asmx” – и CascadingDropDown работает так, как и должен был работать. Ура :)

Заметка опубликована в рубриках: Веб-разработки

Ваше имя: Ваши контакты:
(e-mail или адрес сайта)

Комментарии

Хотите быть первым комментатором этой заметки?

Илья Барков Я занимаюсь веб-разработками, создаю интересные сервисы.
Живу в Днепропетровске.
Весьма разборчив в музыке.

Люблю продукцию компании Apple, пользуюсь Firefox 5 лет, немало работаю с технологиями Microsoft и весьма этим доволен.
  • Сервис отзывов «2 совета»
  • BMW
  • Социальная сеть SunSpace
Если вам интересен мой блог, подписывайтесь на него — feeds.feedburner.com/barkov