ОБНОВЛЕНИЕ: 2009-11-21
Я скачал MVC Release 2 Preview 2 и посмотрел, решена ли эта проблема.
Я сделал быстрый тест и нашел результаты, аналогичные MVC Release 2 Preview 1.
Я не верю, что это исправлено.
ОБНОВЛЕНИЕ: 2009-08-07
Я скачал MVC Release 2 Preview 1 и посмотрел, решена ли эта проблема.
Я вижу новую функцию в сценарии MicrosoftMvcAjax.debug.js, которая называется _serializeSubmitButton , и вижу, что когда Ajax.BeginForm () отображает выходные данные, возникает событие onclick, но при запуске этого события возникает ошибка «Microsoft Ошибка времени выполнения JScript: 'Sys.Mvc.AsyncForm' является нулевым или не является объектом ".
Короче говоря, похоже, что исправление было предпринято, но оно еще не работает, или мне нужно сделать что-то еще. Плохая новость заключается в том, что если это не позднее, то Ajax Forms будут сломаны для всех, пока исправление не будет завершено.
ОБНОВЛЕНИЕ: 2009-05-07
Сегодня я получил отзыв от Microsoft, подтверждающий, что это ошибка. Они зарегистрировали дефект и сказали, что надеются исправить его в следующем выпуске.
Для справки я оставляю подробности своего расследования, которое я отправил в Microsoft. Извиняюсь за длинный пост, но, возможно, он будет полезен всем, кто пытается создать работу вокруг ..
В поддержке Ajax в MVC есть пара проблем. Чтобы проиллюстрировать это, рассмотрим шаблон, показанный в нескольких примерах в Интернете:
//===========
// View.aspx
//===========
<% using (Ajax.BeginForm("Action", "Controller",
new AjaxOptions { UpdateTargetId = "MyControl", HttpMethod = "POST"}))
{ %>
<span id="MyControl">
<% Html.RenderPartial("MyControl"); %>
</span>
<% } %>
//================
// MyControl.ascx
//================
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<input name="startIndex" type="hidden" value="0" />
<%= Ajax.ActionLink("Prev", "PrevAction",
new AjaxOptions() { UpdateTargetId="MyControl", HttpMethod="POST"}) %>
<%= Ajax.ActionLink("Next", "NextAction",
new AjaxOptions() { UpdateTargetId="MyControl", HttpMethod="POST"}) %>
//...
Ожидаемая:
Это просто список, который пользователь может перемещать вперед и назад без обновления всей страницы.
Учитывая эту настройку. Я ожидаю 2 ссылки с пометкой «Предыдущая» и «Следующая». Нажатие на «Prev» должно запустить метод PrevAction в контроллере как пост, и значение в скрытом поле с именем «startIndex» должно быть доступно в параметрах запроса. Я ожидаю аналогичных результатов при нажатии на ссылку Далее.
Фактический:
Реальность такова, что объект запроса содержит NONE параметров формы, хотя он показывает, что он пришел как POST.
Чтобы получить какой-либо из параметров с помощью ссылки на действие, они должны быть явно заданы через вариант ActionLink, который включает параметры. Когда это используется, параметры становятся частью URL ссылки, которая отрицает цель наличия POST.
Так почему же JavaScript неправильный?
Я копался в коде javascript, который используется для обработки отправки для примера, который я разместил со своим вопросом, и теперь я лучше понимаю, почему он не обрабатывает его. Причина, по-видимому, связана с тем, как они связывают события, и что я считаю недостатком в Internet Explorer.
В настоящее время он работает так, что вспомогательный класс Ajax.BeginForm () создает тег формы с функцией onsubmit () для перехвата события отправки формы. Когда пользователь нажимает кнопку отправки, функция onsubmit () запускает и получает параметры, одним из которых является событие.
Сценарии MicrosoftMvcAjax просматривают событие, связывают свойства формы, которые должны быть отправлены, и отправляют запрос на сервер. Проблема в том, что согласно стандартам WC3 должны быть размещены только успешные элементы управления. В случае кнопок отправки это кнопка, которая была фактически нажата. В Internet Explorer нет способа определить, какая кнопка фактически вызвала событие отправки, поэтому скрипт просто пропускает все кнопки отправки.
(В Firefox событие содержит свойство explictOriginalTarget, которое указывает на кнопку, которая фактически вызвала событие в первую очередь)
Что за исправление?
Microsoft должна это исправить. Однако, если нам нужно что-то раньше, я полагаю, что единственный вариант - взломать сценарии MicrosoftMvcAjax, чтобы по-разному связывать события. Я обнаружил, что форму можно связать с обработчиком события mousedown, где нажатая кнопка может быть сохранена в глобальной переменной, где обработчик onsubmit может вставить ее в параметры записи.
Вот код, который я тестировал, чтобы проиллюстрировать эту технику. Я подтвердил, что он работает как в IE8, так и в FireFox, но я еще не пытался взломать его в скриптах MVC Ajax ... Если у меня будет больше времени. Я могу опубликовать результаты здесь.
<script type="text/javascript">
var _clicked = "";
function onSubmit(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) //defeat Safari bug
targ = targ.parentNode;
alert("OnSubmit:" + _clicked + " was clicked.");
return false;
}
function Click(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) //defeat Safari bug
targ = targ.parentNode;
_clicked = targ.name;
return true;
}
<form action="/Home/StandardForm" method="post"
onsubmit="onSubmit(event)" onmousedown="Click(event)">
<input type="submit" name="StdPrev" value="StdPrev" />
<input type="submit" name="StdNext" value="StdNext" />
</form>