从控制器调用表单 OnFailure 处理程序,ASP.NET MVC

Call form OnFailure handler from controller, ASP.NET MVC

如果有人能提供建议,我将不胜感激。

我有一个 Ajax 表格:

  @using (Ajax.BeginForm("Edit", null, new AjaxOptions() { 
                                       UpdateTargetId = updateRegion, 
                                       InsertionMode = InsertionMode.Replace, 
                                       OnFailure = "formFailure" }))
    {}

UpdateTargetId 因当前用户角色而异:

@{
   if (curUser.IsInputer)
    {
        updateRegion = "content";
    }
    else if (curUser.IsAuthorizer)
    {
        updateRegion = "mainPane";
    }
}

如果模型状态无效,我想 return 始终在 mainPane 中查看:

<script>
function formFailure(result)
{
    $("#mainPane").html(result.responseText);        
}
</script>

但是当ModelState 无效时不会调用onFailure。为此,我在控制器中设置错误代码:

public ActionResult Edit(ContractModel entity)
 {
    if(ModelState.IsValid)
    { 
       if(curUser.isInputer) { return RedirectToAction("SomeAction");}
       if(curUser.Authorizer) { return RedirectToAction("OtherAction");}
    }

     Response.StatusCode = 500;//internal server error to fire OnFailure of form
     return PartialView(entity);
 }

然后我得到了想要的结果,即我在 mainPane div 中看到了错误的模型,在浏览器控制台中看到了内部服务器错误。但是,当我在本地 运行 应用程序时,它以这种方式工作,当我在服务器上发布并 运行 它时,我看到错误 500 Internal server error,而不是局部视图。有什么解决方法吗?

编辑: 作为一个选项,我尝试检查模型在 OnSuccess 处理程序中的错误:

    var isValid = @Html.Raw(Json.Encode(ViewData.ModelState.IsValid));

        if (!isValid) {

            $("#mainPane").html(result.responseText);    
        }

但我仍然看到 "content" div 中的视图。为什么会这样?

这很可能发生,因为服务器将 500 解释为未处理的错误并返回默认的 500 错误,因为您在网络配置中的 customErrors 设置可能会翻转为 false 在发布模式下发布应用程序时。

编辑: 删除了使用其他状态代码的提及,因为它引起了更多混乱并且没有解决问题。

这里有一个选项:

不要使用 500 状态错误。那是为了报告您的应用程序出现了严重错误。 这不是这里发生的事情,您只是遇到了表单验证错误。

将您的服务器端代码更新为:

public ActionResult Edit(ContractModel entity)
 {
    if(ModelState.IsValid)
    { 
       if(curUser.isInputer) { return RedirectToAction("SomeAction");}
       if(curUser.Authorizer) { return RedirectToAction("OtherAction");}
    }

    if(!ModelState.IsValid)
    {
        entity.FormError = true; // you will need to add this attribute to your model
    }

    return PartialView(entity);
}

然后在您的局部视图中,放置如下内容:

if(Model.FormError)
{
    @Html.HiddenFor(m => m.FormError)
}

更改表单以处理 OnComplete 事件而不是 OnFailure 事件。这是因为您的 ajax post 没有失败。它成功返回并报告表单输入存在验证错误:

@using (Ajax.BeginForm("Edit", null, new AjaxOptions() { OnSuccess = "handleFormResponse" }))
  {}

将您的处理程序脚本更改为类似这样的内容。这将检查响应以查看是否包含表单错误

  <script>
  function handleFormResponse(result)
  {
        $(result).find("#FormError").length > 0)
        {
            $("#mainPane").html(result);  
        }
        else
        {
            $("#@updateRegion").html(result);
        }

  }
  </script>