Отправка формы Ajax.BeginForm с javascript / jquery, все еще возвращающей частичное представление в виде полной страницы с MVC3 - PullRequest
2 голосов
/ 05 января 2012

( Примечание : обновлено после исходного поста - решение внизу)

Проблема:

Я использую 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, и частичное представление возвращается корректно.

...