javascript - Ajax.BeginForm 处理两个不同的 onSuccess 响应,MVC 5,C#

标签 javascript jquery ajax twitter-bootstrap asp.net-mvc-5

我是 Ajax 和 Jquery 的新手,所以如果我想做一些愚蠢的事情,我需要你原谅我, 我正在使用 MVC 5 和 Ajax.Beginform, 我想做的是我有一个 ajax 表单,我需要用 jquery 不显眼地验证它,如果我做对了,Jquery 验证与 ModelState 一起工作,如果发现验证错误,将再次返回 View ,在这个如果我需要更新我的表单以便验证消息出现在用户浏览器中,例如这是我的 Controller :

[HttpPost]
public ActionResult Index(AddProduct model)
{
    if (ModelState.IsValid)
    {
        // connect to the database save data etc... 
        return PartialView("~/Views/Shared/_MyModal.cshtml");
    }
    else
    {
        return View(model);
    }
}

如果 ModelState.IsValid 我应该保存数据并返回部分 View (Bootstrap Modal),表明数据已成功保存, 否则它将返回整个 View 以显示验证消息,为此我必须将 ajax 表单的 TargetId 放在更新的整个 ajax 表单中, 这里是 ajax 形式:

<div id="result">
 @using (Ajax.BeginForm("Index", new AjaxOptions
  {
      InsertionMode = InsertionMode.Replace,
      UpdateTargetId = "result",
      HttpMethod = "POST",
      OnBegin = "onBegin();",
      OnComplete = "onCompleated();",
      OnSuccess = "onSuccess()",
      OnFailure = "onFailure()"
 }))
 {
@Html.ValidationSummary(true)
<div id="form1" class="form-horizontal">
    <div class="row">
        <div class="form-group">
            @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.Name, new { @class = "form-control"       })
                @Html.ValidationMessageFor(m => m.Name, String.Empty, new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Price, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.Price, new { @class = "form-control" })
                @Html.ValidationMessageFor(m => m.Price, String.Empty, new { @class = "form-help form-help-msg text-red" })
            </div>
        </div>

        <div class="form-group">
            <button class="btn btn-default col-md-2 col-md-offset-2" type="submit">Save &nbsp;&nbsp;</button>
        </div>
    </div>
</div>
 }
  </div>

否则我将返回一个局部 View 并将其显示为 Bootstrap Modal,在这种情况下我需要不更新 ajax 表单 targetId 我需要保持它完整并只显示模态,但问题是在两种情况下 ModelState。 IsValid 或 Is not Valid 所有响应都以 ajax 形式触发 onSuccess 方法 我不知道这些是否正常,这里是 javascript onsuccess() 方法:

function onSuccess() {
    $('#myModal').modal('hide')
    $("#resultModal").modal({
        backdrop: 'static',
        keyboard: false
    });
    $('#resultModal').on('hidden.bs.modal', function (e) {
        window.location = "/product";
    });
}

$(#'myModal').modal('hide') 是一个进度模态,我在发布完成后将其隐藏,下一步是我显示结果模态,如果没有执行正常,我会返回它验证错误, 问题是:

  • 如果验证错误恰好存在,我就可以使用 ajax 表单中的 UpdatetargetId 更新表单,但如果我返回验证错误或部分 View ,则无论如何都会发生这种情况,为我关心模态,在这两种情况下,表格都会消失,这是我不会做的事情, 我需要保留表格,以防返回的内容是部分 View ,并在 ModelStat 验证错误的情况下进行更新,也许我没有理解所有内容,但如果我是,我需要一些解释让我回到正轨。

  • 我做了一个丑陋的代码和困惑,我不喜欢上面提到的 onSuccess() Mehtod,我在关闭结果时使用了事件触发 Modal 再次将我重定向到 Index 所以表单再次显示但是它不干净,我不喜欢它,如果有的话,我需要一些专业的东西。

提前致谢

最佳答案

我完全理解你的问题,我准备向你展示我用来处理这种情况的方法。

因此,因为每次都会调用 onSuccess 方法而不取决于 ModelState 是否有效,所以您需要对响应进行一些不同的处理。 所以你的 [HttpPost] 方法应该是这样的:

 [HttpPost]
        public ActionResult Index(AddProduct model)
        {
            if (ModelState.IsValid)

            {
                return Json(new {isValid = true, data = this.RenderPartialViewToString("ViewWhenModelStasteIsValid",model,false)});
            }
            else
            {
                return Json(new { isValid = false, data = this.RenderPartialViewToString("ViewWhenModelStasteIsNotValid", model, false) });
            }
        }

public static string RenderPartialViewToString(this Controller controller, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

            }
            controller.ViewData.Model = model;

            using (var sw = new StringWriter())
            {
                var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
                var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

在 View 中,您需要从表单中删除 UpdateTargetId 并在成功函数上手动处理它。

所以你的 onSuccess 函数应该是这样的

function onSuccess(result, ref) {
         if (result.isValid) {
           jQuery("#result).html(result.data);
          } else {
            jQuery("#form1").html(result.data);
        }
    }

确保将响应数据传递给 onSuccess 函数,因此您需要将表单从 OnSuccess = "onSuccess()" 更改为 OnSuccess = "onSuccess(data,this )”

因此您的表单将如下所示:

@using (Ajax.BeginForm("Index", new AjaxOptions
  {
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnBegin = "onBegin();",
OnComplete = "onCompleated();",
OnSuccess = "onSuccess(data,this)",
OnFailure = "onFailure()"
 }))

希望这就是您所需要的。

关于javascript - Ajax.BeginForm 处理两个不同的 onSuccess 响应,MVC 5,C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40590142/

相关文章:

javascript - Ajax/jQuery post 之后从 DOM 获取值

javascript - 无法访问javascript中的变量值

javascript - 在 Angular 函数中调用 AJAX

facebook sdk之后的Javascript语句永远不会被执行

javascript - 如何在 Cordova 中几秒钟后执行 JS 代码?

javascript - 在 Promise 调用的错误函数回调之后附加对象的用法是什么

javascript - 我怎样才能根据其中最大标签的最大涨幅来给所有标签页高度

javascript - 服务人员。如何在低连接下使用缓存

javascript - 服务器等待响应时的 Jquery 加载器

ajax - polymer 1.0铁 Ajax