MVC4 Ajax.BeginForm не заменяет UpdateTargetId

В SO есть так много тем о проблемах с Ajax.BeginForm, которые не корректно обновляют целевой элемент с частичным представлением возврата:
mvc4 ajax обновление той же страницы
ASP.NET MVC 4 - Ajax.BeginForm и html5
MVC 4 (razor) - Контроллер возвращает частичное представление, но целая страница обновляется
MVC 4 Ajax не обновляет PartialView на странице
Тем не менее, на все это отвечает либо вручную выписывая jQuery ajax, либо включая отсутствующий файл javascript.

  @using (Ajax.BeginForm("PostcardDetails", new AjaxOptions()
  {
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "details"
  }))
  {
    <div id="PostcardSearchResults">
      @{Html.RenderAction("PostcardSearchResults", Model);}
    </div>
  }
  <div id="details">
  </div>

Соответствующий код контроллера:

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult PostcardSearchResults(PostcardSearchFilter filter)
{
        PostcardSearchResults model = new PostcardSearchResults(filter);
        return PartialView("_PostcardSearchResults", model);
}

В моем макете я ссылаюсь на эти файлы jQuery. Кроме того, я проверил, что страница выводит правильный путь и находит правильные файлы. Я попытался переключить порядок unobtrusive-ajax.min.js и validate.min.js, чтобы не получилось.

<script type="text/javascript" src="@Url.Content("~/Scripts/globalize.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-ui-1.10.0.custom.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

Кроме того, на моем веб-сайте root web.config и в web.config в моей папке View я включил:

<add key="webpages:Version" value="2.0.0.0"/>
<add key="PreserveLoginUrl" value="true"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

Я не понимаю, где еще искать. Ошибок javascript не выбрасывается, и контроллер правильно попадает, возвращая PartialViewResult. Элемент Form в HTML заполняет все правильные атрибуты data-.

Ответ 1

Возникает проблема с jquery.unobtrusive-ajax.min и JQuery 1.9, потому что JQuery 1.9 не поддерживает метод live() any больше. Поэтому вы должны использовать плагин миграции JQuery и ссылаться на JQuery migrate js.

Ответ 2

Убедитесь, что вы включили ненавязчивый-ajax.js на страницу, на которую вы разместили свою форму ajax.

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

Ответ 3

У меня была эта проблема, я только что установил последний ненавязчивый пакет из NuGet и решил проблему

PM > Установить пакет Microsoft.jQuery.Unobtrusive.Ajax

Вам понадобится JQ 1.8 +

Ответ 4

У меня были схожие проблемы: у меня были все мои скрипты в комплекте и загрузка правильно, и все коды были выполнены правильно. Я проверил диспетчер пакетов, чтобы проверить, нужно ли обновлять какие-либо скрипты, и jQuery и jquery.unobtrusive-ajax. jQuery перешел с 1.9 до 1.9.1. Когда я перестроил свое решение, целевой DIV был успешно обновлен. Попробуйте и обновите все JS в своем решении, это может сработать.

Ответ 5

Следующее должно быть на любой странице, использующей ajax.

@section Script {
    @Scripts.Render("~/bundles/jqueryval")
}

Ответ 6

Я не знаю, будет ли кто-то еще сталкиваться с этим, но в моем случае он, похоже, не обновлялся. Я создавал простую форму редактирования, в которой вы выбираете элемент, который хотите изменить, из раскрывающегося списка, нажмите кнопку, и AJAX загрузит форму редактирования для выбранного элемента.

Он работал в первый раз, но после изменения моего выбора в выпадающем списке и нажатия кнопки ни одно из значений формы не изменилось, хотя я подтвердил, что мой серверный код загружал новый элемент в модель представления, Поэтому оказалось, что Replace не работает. После перехода через jquery.unobtrisive-ajax.js я обнаружил, что он заменял содержимое моего целевого элемента, только с той же самой разметкой вида, что и раньше, что не соответствовало модели, которая была передана в представление!

Что, когда я понял, это меня доставало ModelState. Во второй раз, когда я нажал кнопку загрузки, он предоставил мой вариант выпадающего списка, а также мою заполненную форму редактирования. Все значения в форме редактирования были добавлены в ModelState (как и следовало ожидать). Затем мой код контроллера заменил представленную модель представления (то, что связующее устройство, созданное из значений формы редактирования), с моделью просмотра для выбранного значения выпадающего списка и передал его частичному представлению. Однако в частичном представлении используется куча методов-помощников Html.[X]For. Они игнорируют обновленную модель представления и вытаскивают свои значения непосредственно из ModelState. Например:

@Html.DisplayFor(m => m.Name)
@Model.Name

отобразится два разных значения для Name; первый - отображаемое имя, а второе - обновленное имя. Это механизм, который позволяет MVC запоминать записи вашей пользовательской формы после ошибки проверки (на стороне сервера). В этом случае, поскольку это частичная загрузка страницы, и я просто выбрасываю все представленные значения, мне не нужны никакие значения ModelState, поэтому я просто вызываю ModelState.Clear() перед возвратом моего представления для обновленного просмотреть модель.

    public ActionResult GetItemEditForm(EditItemsViewModel editItemsVM)
    {
        if (editItemsVM.SelectedItemID != null)
        {
            //Load the selected item
            ItemsModelManager.GetEditItemsVM(editItemsVM);

            //Clear the submitted form values
            ModelState.Clear();
        }

        return PartialView("_ItemsEditor", editItemsVM);
    }

Ответ 7

Для тех, кому нужно немного больше объяснений....

Введите это в консоли диспетчера пакетов PM > Install-Package jQuery.Migrate

Ссылка на это в частичном просмотре:

script src= "~/Scripts/jquery.unobtrusive-ajax.js" >

Счастливое кодирование всех.

Ответ 8

Пользователь xr280xr отвечает за включение

ModelState.Clear();

работал у меня. Приложение, с которым я работаю, находится на более раннем jQ (1.7.x), поэтому миграция не будет работать в нашей ситуации. Очистка состояния модели в контроллере сделала именно то, что мы ожидали от BeginForm.

Ответ 9

Проверьте главную страницу или ваши скрипты страниц. jquery.unobtrusive-ajax.js если не добавить ссылку об этом js: jquery.unobtrusive-ajax.js

Ответ 10

Метод live() был устарел в jQuery версии 1.7 и удален в версии 1.9. Используйте метод on(). Для получения дополнительной информации обратитесь: http://www.w3schools.com/jquery/event_live.asp

Ответ 11

Ничего себе, здесь есть много ответов. Моя проблема была вызвана панелью загрузки. Это создало "вложенную" панель. Я удалил разметку панели и просто использовал простой старый div, и это сработало. Я думаю, UpdateTargetId должен быть прямым родителем формы AJAX.

Вот html, иллюстрирующий проблему.

<div class="panel panel-default" id="notes-form">
  <div class="panel-body">
    @using (Ajax.BeginForm("EditNote", new { id = Model.Id }, new AjaxOptions { UpdateTargetId = "notes-form" }, htmlAttributes: new { @class = "form-horizontal" }))
    {
    }
  </div>
</div>

Ответ 12

Сначала установите " Microsoft.JQuery.Unobtrusive.Ajax" из NuGet Manager, а позже включите " ~/Scripts/jquery.unobtrusive" в " BundleConfig" после включения " jquery- {version}.js"; который будет выглядеть примерно так:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js",
                "~/Scripts/jquery.unobtrusive*));