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>

Кроме того, в корневой файл 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. Элемент формы в HTML заполняет все правильные атрибуты data-.


person drovani    schedule 26.02.2013    source источник


Ответы (12)


Существует проблема с jquery.unobtrusive-ajax.min и JQuery 1.9, потому что JQuery 1.9 не поддерживает метод live() любой больше. Поэтому вам следует использовать подключаемый модуль переноса JQuery и ссылаться на файл переноса JQuery js.

person Gabriel Monteiro Nepomuceno    schedule 26.02.2013
comment
Немного запутался, какое это имеет отношение к проблеме ОП? Вы говорите, что .live — это то, что Ajax.Beginform использует под капотом? - person InspiredBy; 26.02.2013
comment
Забыл упомянуть, что я уже обновил свой `jquery.unobtrusive-ajax.min.js' предложениями из этого поста: stackoverflow. com/a/14512797/28310 Если бы я этого не сделал, я бы получал ошибки JavaScript. Я также пытался использовать jquery-migrate. - person drovani; 26.02.2013
comment
Да, Ajax Beginform использует live под капотом - person Gabriel Monteiro Nepomuceno; 26.02.2013
comment
Контроллер вызывается правильно? и что вы получили, когда вы получили возвращение? - person Gabriel Monteiro Nepomuceno; 26.02.2013
comment
Я добавил код действия в контроллер. Он возвращает PartialView, отображаемый правильно, но браузер заменяет всю страницу таблицей, а не помещает ее в div #details. - person drovani; 27.02.2013
comment
Вы используете MVC4, поэтому вам не нужно использовать @Url.Content(~/Scripts/globalize.js) только ~/Scripts/globalize.js сценарий, который вы описываете, обычно происходит, когда на сценарии ссылаются неправильно - person Gabriel Monteiro Nepomuceno; 27.02.2013
comment
В итоге я вернул свой jquery.unobtrusive-ajax.min.js обратно в исходный файл (который возвращает его к использованию метода live() и включает подключаемый модуль миграции jQuery. Это решило проблему. - person drovani; 03.03.2013
comment
Это решило мою проблему!!! Хотел бы я прочитать это за 5 часов до того, как удариться головой о стол!.. Спасибо, Габриэль. - person nav; 23.10.2013

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

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
person Cyrus    schedule 09.11.2014

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

PM>Установочный пакет Microsoft.jQuery.Unobtrusive.Ajax

Потребуется JQ 1.8+

person Andy    schedule 27.04.2014

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

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

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

@Html.DisplayFor(m => m.Name)
@Model.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);
    }
person xr280xr    schedule 23.09.2015
comment
Спасибо френ. Ваш ответ заставил меня снова оглянуться на код, чтобы понять, что предыдущий разработчик возвращал Content(singleProperty) вместо PartialView(model), чего и ожидала моя обновленная разметка. - person TechSavvySam; 23.06.2020

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

person MattSull    schedule 03.03.2013

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

@section Script {
    @Scripts.Render("~/bundles/jqueryval")
}
person user3015361    schedule 20.11.2013

Вау, здесь много ответов. Моя проблема была связана с панелью начальной загрузки. Это создавало «вложенную» панель. Я удалил разметку панели и просто использовал старый добрый 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>
person Jess    schedule 12.08.2016

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

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

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

сценарий src="~/Scripts/jquery.unobtrusive-ajax.js">

Всем удачного кодирования.

person cyclical    schedule 04.03.2015

Ответ пользователя xr280xr для включения

ModelState.Clear();

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

person Jason Turnage    schedule 10.11.2015

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

person Steven.Qiu    schedule 13.01.2016
comment
добавить что? Это неполный ответ. - person AndroidMechanic - Viral Patel; 13.01.2016
comment
Ссылка на это: jquery.unobtrusive-ajax.js - person Steven.Qiu; 25.01.2016

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

person Madhusudhan V Indian    schedule 17.06.2016

Сначала установите «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*));
person Radha Anil K    schedule 22.12.2016