当Model.State无效触发OnSuccess函数时,Ajax.Beginform进行验证

时间:2013-10-28 18:50:08

标签: jquery ajax asp.net-mvc-4 asp.net-ajax

这显然是一个陈旧的话题,但我无法提出解决以前帖子的解决方案。希望有人可以告诉我这样做的“正确方法”,因为我需要做很多事情。

主要问题:当Ajax.Beginform发布ModelState无效时,它仍会触发OnSuccess方法。我知道这是正确的行为,但我的OnSuccess方法做的事情只有在(go figure)帖子“成功”时才有意义。

在这种情况下,如何最好地管理带有验证错误的重新显示表单?如何从我的控制器返回success = false以及要重新显示的视图?

这与问题没有特别的关系,但是我在这里做的事情有点像尝试在Bootstrap模式中显示一个表格,我放弃了。

1)通过ajax调用控制器在div中加载表单。

$(function addpaneevent() {
    $('.addpane').on("click", function () {
        var url = '/QuizPane/QuickPane?quizId=' + $(this).data("quizid");
        $.ajax({
            url: url,
            type: 'GET',
            contentType: 'application/json',
            success: function (result) {
                $('#overlay').html(result);
            },
            error: function (result) {
                console.log("bummer",result);
            }
        });
    });
});

2)返回包含表单的部分视图

public ActionResult QuickPane(int quizId)
{
    var model = *querytogetmodel*
    return PartialView("QuickPane",model);
}


@using (Ajax.BeginForm("QuickPane", "QuizPane", FormMethod.Post,
    new AjaxOptions
    {
                            InsertionMode = InsertionMode.Replace,
                            HttpMethod = "POST",
                            OnSuccess = "updatePaneList(data)",
                            OnFailure = "massivefail(data)",
    }))
{
   @Html.ValidationSummary(true)

    <fieldset>
        @Html.HiddenFor(model => model.QuizID)
        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.Title, new { @autofocus = "autofocus" })
            @Html.ValidationMessageFor(model => model.Title)
        </div>
        ...more of the same
        <input type="submit" value="Create" class="btn btn-primary"/>
    </fieldset>
}

3)提交电话留言

[HttpPost]
public ActionResult QuickPane(QuizPane quizpane)
{
    if (ModelState.IsValid)
    {
        db.QuizPanes.Add(quizpane);
        db.SaveChanges();
         return PartialView("_quizpanelist", quizpane);
    }
    return View(quizpane); //tried a few different things here
 }

4)成功后我将新记录添加到表中并删除包含输入表单的div。

function updatePaneList(data) {
    $("#overlay").remove();
    var rowcount = $(".expanded #panetable tr:last").count;
    $('.expanded #panetable  tbody:last').append(data);        
};

4 个答案:

答案 0 :(得分:4)

我通过执行以下操作解决了这个问题...虽然我不知道这是否是一种建议的方法来处理它。此外,您应该在两种情况下都返回局部视图。

在返回局部视图之前,添加以下行

Response.AppendHeader("X-Error", "true")

然后在你的javascript onsuccess

function doOnSuccess(data, status, xhr) {
   if (xhr.getResponseHeader('X-Error')) {
      //validation error occurred
   }
   else
   {
      //validation error did not occur
   }
}

答案 1 :(得分:0)

我不会使用Ajax.BeginForm,而是使用普通表单并使用ajax调用。

$(document).on('click', '.btn-primary', function(){
    $.ajax({
        url: '@Url.Action('QuickPane', 'QuizPane')',
        type: 'post',
        data: {
            Title: $('#Title').val()
        }
        success: function(result){
            //Do Something
        }
        error: function(result){
            //Display error
        }
    });
});

然后在您的控制器中返回JSON而不是部分视图,您可以设置错误,如return Json error from ASP.NET MVC或成功,如ExtJS: how to return json success w/ data using asp.net mvc 希望这会有所帮助。

答案 2 :(得分:0)

这是因为OnSuccess vs OnFailure没有以任何方式连接到ModeState.IsValid

根据AjaxOptions docs

  

OnSuccess:如果响应状态 在200范围内,则会调用此函数。
  OnFailure:如果响应状态不是在200范围内,则会调用此函数。

换句话说,您必须通过更改Response.StatusCode并在OnFailure js方法中返回您期望的任何值来手动指定返回ActionResult时出现故障。

[HttpPost]
public ActionResult Search(Person model) 
{
  if (ModelState.IsValid) {
    // if valid, return a HTML view inserted by AJAX helper
    var results = PersonRepository.Get(model)
    return PartialView("Resulsts", vm);

  } else {
    // if invalid, return a JSON object and handle with OnFailure method
    Response.StatusCode = (int)HttpStatusCode.BadRequest;
    return Json(new { errors = ModelState.Values.SelectMany(v => v.Errors) });

  }
}

进一步阅读

答案 3 :(得分:0)

仅在结果成功时使用if / else

       $("#SaveStudentRecord").click(function () {
            var data = $("#SubmitForm").serialize();  
            $.ajax({
                method: "POST",
                url: '@(Url.Action("EditAdd", "Ucesnik"))',
                data: data,
                success: function (result) {
                    if (result.success) {
                        alert("Success!..");
                        window.location.href = "/Ucesnik/GetUcesnici";
                        $("#MyModal").modal("hide");
                    }
                    else {
                        alert("Not successful");
                    }
                }
            })
        })