( Примечание : обновлено после исходного поста - решение внизу)
Проблема:
Я использую MVC3 и создал частичное представление с помощью Telerik ComboBox с использованием Ajax.BeginForm, а затем пытаюсь передать его, используя обработчик javascript, присоединенный к ComboBox, как клиентское событие.
Однако всякий раз, когда он отправляет и попадает в контроллер, Request.IsAjaxRequest () возвращает false, и поэтому он не обрабатывается как запрос ajax. Если я добавлю отдельную кнопку отправки и отправлю форму, используя ее, то в контроллере Request.IsAjaxRequest () вернет true.
На данный момент результатом является то, что мой PartialView возвращается как полная страница, а не заменяет необходимый div. Со ссылкой на источник ниже это BUserControl, который возвращается из контроллера, но в виде полной страницы.
Я также пытался использовать не Telerik DropDownList и получил тот же результат.
Если кто-то может определить, что может быть не так, я был бы очень признателен.
Вот страница Razor, которая содержит частичные представления:
@inherits ABC.DEF.Site.ViewClasses.ViewModelView<ABC.DEF.Site.Models.ViewModel>
@{
ViewBag.Title = "DEF - View Creation";
}
<div class="editor-label">
@Html.Label("System", "System")
</div>
<div class="editor-field">
@Html.Partial("AUserControl", Model)
</div>
<div class="editor-label">
@Html.Label("Type", "Type")
</div>
<div class="editor-field" id="B">
@Html.Partial("BUserControl", Model)
</div>
Вот частичное представление для AUserControl
@inherits ABC.DEF.Site.ViewClasses.ViewModelView<ABC.DEF.Site.Models.ViewModel>
@using (Ajax.BeginForm("LoadB", "View", new AjaxOptions { UpdateTargetId = "B" }))
{
@(Html.Telerik().ComboBoxFor(m => m.SelectedA)
.BindTo(new SelectList(GetExistingViewData.As, "Id", "DisplayName"))
.HtmlAttributes(new { style = string.Format("width:{0}px", 500) })
.ClientEvents(events => events.OnChange("onSelectedAChange"))
)
}
<script type="text/javascript">
function onSelectedAChange()
{
$(this).parents('form').submit();
}
</script>
Вот частичное представление для BUserControl (обратите внимание, что оно ссылается на div "C", который я намеренно пропустил со страницы Razor выше в этом посте для краткости):
@inherits ABC.DEF.Site.ViewClasses.ViewModelView<ABC.DEF.Site.Models.ViewModel>
@using (Ajax.BeginForm("LoadC", "View", new AjaxOptions { UpdateTargetId = "C" }))
{
@(Html.Telerik().ComboBoxFor(m => m.SelectedB)
.BindTo(new SelectList(GetExistingViewData.GetBs(Model.SelectedA), "Id", "DisplayName" ))
.HtmlAttributes(new { style = string.Format("width:{0}px", 500) })
.ClientEvents(events => events.OnChange("onSelectedBChange"))
)
}
<script type="text/javascript">
function onSelectedBChange() {
$(this).parents('form').submit();
}
</script>
И, наконец, вот функция Controller, которая вызывается при изменении Combo в AUserControl:
[HttpPost]
public ActionResult LoadBs(ViewModel model)
{
PartialViewResult res = PartialView("BUserControl", model);
return res;
}
Именно в этой функции контроллера, если я набираю Request.IsAjaxRequest () в ближайшем окне, он возвращает false.
Вещи, которые я проверял (как много раз предлагалось в других местах):
- Я включил файл jquery.unobtrusive-ajax.min.js в свой _Layout.cshtml
- Я включил запись key = "UnobtrusiveJavaScriptEnabled" value = "true" в web.config для сайта
- Я не включаю старые файлы MVCAjax js
- Изменение страницы и частичных представлений так, чтобы тег @model находился вверху вместо @inherits - это не имело никакого эффекта
Это предложения, такие как в этом подобном вопросе
Другие детали:
- Он работает на IIS 7, Windows 7 и браузер IE8
- У меня есть отдельный пример проекта, который очень похож и отлично работает, и я не вижу каких-либо существенных различий между ними.
-------- ЭТО ТЕПЕРЬ РАЗРЕШЕНО В СООТВЕТСТВИИ С НИЖЕ РЕШЕНИЕМ --------
Наконец-то решил эту проблему через два дня - отправив ответ, чтобы, если у других возникла такая же проблема, это им помогло!
На нашей странице _Layout.cshtml мы включаем следующую строку в раздел head, чтобы включить библиотеку jQuery:
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
Но поскольку мы используем элементы управления Telerik MVC, на нашей странице _Layout.cshtml также была следующая строка:
@Html.Telerik().ScriptRegistrar();
Здесь регистрируется правильное включение javascript для элементов управления Telerik.
И по умолчанию это добавляет следующее в конце страницы:
<script src="@Url.Content("~/Scripts/2011.3.1115/jquery-1.6.4.min.js")" type="text/javascript">
Эта более новая версия jquery (или включающая оба) явно вызывает проблемы с отправкой формы ajax, поскольку я затем включил эту строку в мой другой пример проекта (который полностью работал), и она сломалась.
Итак, вернемся к основному проекту - незначительное изменение строки регистрации скрипта Telerik удаляет стандартное включение jQuery и все работает.
@Html.Telerik().ScriptRegistrar().jQuery(false);
Контроллер теперь распознает отправку как правильную обратную передачу Ajax, и частичное представление возвращается корректно.