代码之家  ›  专栏  ›  技术社区  ›  Chris F

帮助了解ASP.NET MVC呈现引擎为何产生意外的HTML结果

  •  0
  • Chris F  · 技术社区  · 16 年前

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

    我在ASP.NET MVC中使用jQuery ajaxSubmit和一个只接受POST谓词并返回PartialViewResult的操作来完成此操作。我在我的网站上的几个地方都这样做,但是我在一个页面上有两个这样的工作流。一个工作,另一个不工作,使用相同的代码。

    问题是:

    <% 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");
        }
    }
    

    1 回复  |  直到 16 年前
        1
  •  0
  •   Chris F    16 年前

    此问题的根本原因与在回发和重新呈现页面期间如何使用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”隐藏字段的显式设置(因为隐藏字段是以post-back的形式捕获的)。

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

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