【问题标题】:Call form OnFailure handler from controller, ASP.NET MVC从控制器调用表单 OnFailure 处理程序,ASP.NET MVC
【发布时间】:2015-03-07 16:42:58
【问题描述】:

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

我有一个 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";
    }
}

如果模型状态无效,我希望始终返回 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);    
        }

但我仍然可以在“内容”div 中看到视图。为什么会这样?

【问题讨论】:

    标签: c# jquery asp.net asp.net-mvc asp.net-ajax


    【解决方案1】:

    这是一个选项:

    不要使用 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 帖子没有失败。它成功返回并报告表单输入存在验证错误:

    @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>
    

    【讨论】:

    • 感谢您的回复,但它的工作方式与我上次编辑的方式相同。我在“内容”div 中看到了 responseText。
    • 我不这么认为。您正在使用: var isValid = @Html.Raw(Json.Encode(ViewData.ModelState.IsValid)) 设置“isValid”一次,当页面第一次加载时。 ajax 表单不会重新加载页面,因此不会再次执行该行。您需要在 ajax 调用之后再次将 ModelState.IsValid 发送回客户端...按照我上面的示例。
    • 好的,同意。我试过你的答案,它对我不起作用,如果 formError 为真,我仍然会得到“内容”div中的所有内容。
    • 您能在表单发布后返回的标记中看到带有 Id="FormError" 的隐藏输入吗?
    • 好的,听起来我们没有正确使用结果对象。我的最后一个建议是完全删除“UpdateTargetId”参数并在 OnSuccess 方法中处理 HTML 填充。生病编辑我的原始答案以反映这一点。这里使用这种方法:stackoverflow.com/questions/12562857/…
    【解决方案2】:

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

    编辑:删除了使用另一个状态码的提及,因为它会引起更多的混乱并且不能解决问题。

    【讨论】:

    • 我仍然看到错误“400 Bad Request”。我认为设置 Response.StatusCode 不是一个选项,我应该看到有错误的模型而不是错误消息。
    • 您根本不需要响应代码,即使没有它,模型错误也应该显示给您,如果我没记错的话,由于InsertionMode 参数而导致的javascript方法。您想使用响应代码有什么原因吗?
    • 是的,我知道我可以看到没有响应代码的模型错误,但我的问题是我根据当前用户角色使用不同的 UpdateTargetIds。但是如果模型返回一些错误,我需要留在“mainPane”div中,不管角色。
    • 你能不能让 PartialView 同时包含updateRegions 然后只有一个更新目标?我能想到的替代方法是将 ActionResult 更改为包含 status 和视图作为字符串的 json 结果。或者,如果存在模型错误,则将服务器的输出解析为您在局部视图中设置的隐藏输入。 See the responses to this question
    • 在HttpPost动作中返回Json可以吗?那么我应该在jQuery中总结表格吗?我没有得到你关于解析输出的最后一点,你能提供一个例子吗?
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 2018-06-18
    相关资源
    最近更新 更多