即使模型无效,ASP.NET MVC“Ajax.BeginForm”也会执行 OnSuccess

Posted

技术标签:

【中文标题】即使模型无效,ASP.NET MVC“Ajax.BeginForm”也会执行 OnSuccess【英文标题】:ASP.NET MVC "Ajax.BeginForm" executes OnSuccess even though model is not valid 【发布时间】:2011-11-11 20:09:51 【问题描述】:

我有一个“提交反馈”表单,它使用“Ajax.BeginForm”来呈现包含表单元素的部分。即使 ModelState 无效,也会触发 OnSuccess 事件。这是正常的吗?我希望能够进行一些回发,从而导致模型无效,然后当模型有效且没有错误时,会触发 OnSuccess 事件?

【问题讨论】:

我同意这是不必要的复杂工作。我们显然需要一个简单的值来指示模型是否有效。 【参考方案1】:

我用一种相当简单的 javascript 技术来处理这个问题:

首先像这样设置你的OnSuccess

OnSuccess = "UpdateSuccessful(data)"

然后你的javascript函数是这样的:

function UpdateSuccessful(data) 
    if (data.indexOf("field-validation-error") > -1) return;

    // Do your valid stuff here

这样一来,就不需要弄乱你的控制器,或者更重要的是,你的控制器可以返回带有模型错误的Partial View,而不会做任何奇怪的事情,即:

    public ActionResult SaveDetails(Project model)
    
        if (ModelState.IsValid)
        
            model.SaveProject();
        

        return PartialView("ProjectForm", model);
    

在你的AjaxOptions:

UpdateTargetId = "FormContents"

现在只要确保你有一个div 或带有id="FormContents" 的东西,无论你想在哪里显示你的表单。

【讨论】:

OnSuccess = "UpdateSuccessful(data)" :真的很有帮助。谢谢。 这个 'data' 对象是否适用于所有浏览器?它有任何限制或兼容性问题吗? 这应该适用于所有启用 JavaScript 的浏览器。 我使用@html.ValidationSummary() 所以需要检查一下: if (data.indexOf("validation-summary-errors") > -1) 这就是我要找的。好,易于。谢谢!【参考方案2】:

这正常吗?

是的,当然。如果服务器发送 HTTP 200,则调用 OnSuccess 方法。模型状态有效性的概念仅适用于服务器端。只要您的控制器操作返回一些视图/部分/json/... OnSuccess 就会触发。如果在您的控制器操作中引发异常,则将触发 OnError 而不是 OnSuccess。

因此,为了处理这种情况,您可以让您的控制器操作执行以下操作:

[HttpPost]
public ActionResult Process(MyViewModel model)

    if (!ModelState.IsValid)
    
        return Json(new  success = false );
    
    return Json(new  success = true );

然后:

function success(result) 
    if (result.success) 
        // the model was valid
     else 
        // the model was invalid
    

现在,在模型无效的情况下,您可能希望通过刷新表单向用户显示错误消息。在这种情况下,您可以做的是将您的表单放在一个局部中,如果模型状态无效,您将从控制器操作返回一个局部视图,如果成功则返回一个 json 对象。所以在你的成功处理程序中你可以测试:

function success(result) 
    if (result.success) 
        // the model was valid
     else 
        // there were errors => show them
        $('#myform_container').html(result);
        // if you are using client side validation you might also need
        // to take a look at the following article
        // http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
        // and reattach the client validators to the form as you are
        // refreshing its DOM contents here
    

【讨论】:

谢谢谢谢。这个答案很完美。我很惊讶没有可靠的文档来处理这种不显眼的 AJAX 内容(模型错误)。 对我不起作用,因为失败时,我必须返回视图,而不是 JSON。 我认为首先你必须检查结果的类型: if (typeof(result) == "object" && result.success) 我在局部视图中执行此操作,并且错误地需要重新加载局部视图,因此使用 'replaceWith' 而不是 'html': $('#myform_container').replaceWith(result);【参考方案3】:

您可以执行以下操作:

var OnSuccess = function() 
    if ($(".validation-summary-errors").length == 0)  
        //Your javascript/jquery code goes here
    

【讨论】:

【参考方案4】:

Luis 的回答略有不同:

function OnSuccess() 
    if ($("span[class='field-validation-error']").length == 0) 
        alert("Target Platform saved Successfully.");
    

【讨论】:

【参考方案5】:

我返回一个错误请求而不是视图,以确保 ajax 调用返回 onfail 而不是 onsuccess。

在 xhr.statustext 中可以找到写在 bad request 中的字符串,并正确管理 onfail 事件。

服务器端:

if (!ModelState.IsValid)
        
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Model not valid");
        

客户端:

$.ajax(
        url: '',
        method: 'POST'            
       ).fail(function (xhr) 
           alert(xhr.statustext);
       );

【讨论】:

以上是关于即使模型无效,ASP.NET MVC“Ajax.BeginForm”也会执行 OnSuccess的主要内容,如果未能解决你的问题,请参考以下文章

在 asp.net mvc 模型中更新用户配置文件无效

ASP.NET MVC 4 模型验证

ASP.NET MVC 4 模型验证

ASP.Net MVC 5 Html.BeginForm onsubmit 和具有所需属性的模型

ASP.NET MVC - 存储过程执行返回无效对象

ASP.NET MVC 页面验证失败(值无效。)