0

我有一个带有表单的模式弹出窗口。当通过 ajax(使用 jQuery)提交时,表单被验证并且一个 javascript 回调函数检查模型是否有效。如果是,则重置并隐藏模式弹出窗口,如果不是,则将 html 响应文本转储到模式弹出 div 中,以供用户查看故障。

我在 ASP.NET MVC 中使用 jQuery ajaxSubmit 和仅接受 POST 动词并返回 PartialViewResult 的操作来执行此操作。我在我网站上的几个地方执行此操作,但是在 2 个这样的工作流程关闭 1 页时遇到问题。一个有效,另一个无效,使用相同的代码。

这是问题所在:

<% using (Html.BeginForm("ApplyPayment", "SomeController", FormMethod.Post, new { @id = "frmApplyPayment" })) { %>
    <%= Html.AntiForgeryToken(SomeSaltString) %>
    <%= Html.Hidden("ModelValid", ViewData.ModelState.IsValid) %>
    ...
<% } %>

在调试过程中,即使在出现验证错误时 ViewData.ModelState.IsValid 为 false,“#ModelValid”也会设置为“True”!我尝试了许多将其显式设置为 false 的方法(例如 ViewData.ModelState.IsValid ? "True" : "False")。即使变量为假并隐藏弹出窗口,它也总是显示为真。到底是怎么回事?

这里有更多代码供参考:

function SubmitPaymentForm(form) {
    $(form).ajaxSubmit({ target: "#modalApplyPayment", success: CheckPaymentValidity  });
}

function CheckPaymentValidity(responseText) {
    if ($("#ModelValid").val() != "True") {
        ShowModalPopup("#modalApplyPayment");
    }
    else {
        HideModalPopup("#modalApplyPayment");
    }
}

这一切都完全适用于电子邮件功能的相同基本页面的非常相似的工作流程(接受地址的弹出窗口,在 ajax 帖子上验证,如果存在验证错误则显示弹出窗口)。

4

1 回答 1

0

此问题的根本原因与在回发和重新呈现页面期间如何使用 ModelState 有关。我的验证系统使用这种方法:

TrasnferValidationMessagesTo(ModelStateDictionary modelState,
                             IList<IValidationResult> results,
                             FormCollection formValues)
{
    // Set the ModelValue in modelState for each key in formValues

    // Add a ModelError for each error in results
}

我相信 ASP 的引擎旨在利用 ModelState 集合中的值来重新填充表单的值。这将秘密地覆盖我对“#ModelState”隐藏字段的显式设置(因为隐藏字段是在表单回发中捕获的)。

令人惊讶的是,我发现如果我的 ModelState 保留了上一篇文章中“#ModelValid”的“True”值,并且我尝试使用代码将其显式设置为“False”,它将无法正常工作。但是如果我把它颠倒过来,从“False”开始并设置为“True”,它工作得很好。

我的解决方案是在我的视图模型中添加一个 ModelValid 属性并将其默认为 false 并在没有验证错误时将其设置为 true 并使用它来修改“#ModelValid”。我的其他模式弹出窗口没有同样的问题,因为在那里我使用了手动验证,并且 ModelState 从未使用上一篇文章中的表单值更新。

于 2010-02-10T16:30:59.430 回答