更新: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 表单都会被破坏。
更新:2009-05-07
我今天收到来自 Microsoft 的反馈,确认这是一个错误。他们已经记录了这个缺陷,并表示希望在未来的版本中修复它。
作为参考,我将提交给 Microsoft 的调查详细信息留下。对长篇文章的请求,但也许它对任何试图创建解决方法的人都有用..
MVC 中的 Ajax 支持存在一些问题。为了说明,请考虑网络上几个示例中说明的模式:
//===========
// 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”的隐藏字段中的值应该在请求参数中可用。单击“下一步”链接时,我希望得到类似的结果。
实际:
现实情况是,请求对象不包含任何表单参数,即使它显示它是作为 POST 进来的。
为了使用操作链接获取任何参数,必须通过包含参数的 ActionLink 变体显式提供它们。使用此参数时,参数将成为链接 URL 的一部分,这违背了 POST 的目的。
那么为什么 javascript 出错了?
我深入研究了用于处理提交问题的示例的 javascript 代码,现在我更好地理解了为什么它不处理它。原因似乎与他们连接事件的方式以及我认为 Internet Explorer 的一个缺点有关。
目前的工作方式是 Ajax.BeginForm() 辅助类生成一个带有 onsubmit() 函数的表单标签来拦截表单提交事件。当用户单击提交按钮时,onsubmit() 函数会触发并接收参数,其中之一就是事件。
MicrosoftMvcAjax 脚本查看事件,捆绑应该提交的表单属性并将请求发送到服务器。问题在于,根据 WC3 标准,应该只发布 成功 控件。在提交按钮的情况下,这是实际单击的按钮。在 Internet Explorer 下,无法确定是哪个按钮实际触发了提交事件,因此脚本只会跳过所有提交按钮。
(在 Firefox 中,该事件包含一个名为“explictOriginalTarget”的属性,该属性指向首先实际导致该事件的按钮)
解决方法是什么?
微软应该修复它。但是,如果我们需要更快的东西,我相信唯一的选择是破解 MicrosoftMvcAjax 脚本以不同的方式连接事件。我发现表单可以连接到一个 mousedown 事件句柄,在该事件中,单击的按钮可以保存在一个全局变量中,onsubmit 处理程序可以将其插入到 post 参数中。
这是我测试的一些代码来说明这种技术。我已经确认它适用于 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;
}