我有一个 MVC5 应用程序,我刚开始在上面做一些 Ajax。 我有一个带有按钮的页面,单击该按钮会打开一个带有来自另一个操作的表单的 Bootstrap 模式。但是,当提交该模态表单时,不会调用 jquery 不显眼的验证,并且页面会重定向到空白页面上的部分视图,而不是在模态对话框内。
所以,1:我怎样才能让 jquery 验证在模态内工作, 和2:如何使表单不刷新页面,而是将返回的视图重新加载到模态中? 和 3:我对 Ajax.BeginForm 应该如何工作感到困惑,因为我认为它不会创建页面刷新。
这是包含加载模式按钮的页面:
@using Plus.ViewModels
@model UserViewModel
@{
ViewBag.Title = "Personal Details";
}
@using (Html.BeginForm(null, null, FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.AntiForgeryToken()
// A separate form here
<div class="form-actions">
<button class="btn btn-primary" type="submit">
<i class="fa fa-save"></i>
Save
</button> |
<a class="btn btn-primary" href="@Url.Action("ChangePassword", "Manage", new object{})" data-toggle="modal" data-target="#myModal">Change Password</a>
</div>
}
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
@section Scripts {
<script type="text/javascript">
$('#myModal').on('shown.bs.modal', function () {
jQuery.validator.unobtrusive.parse($(this));
})
</script>
}
包含我要在模态对话框中提交的表单的视图:
@model Plus.ViewModels.ChangePasswordViewModel
@{
ViewBag.Title = "Change Password";
Layout = "";
AjaxOptions options = new AjaxOptions();
options.HttpMethod = "POST";
options.Url = Url.Action("ChangePassword", "Manage");
options.UpdateTargetId = "modalForm";
options.InsertionMode = InsertionMode.Replace;
}
@using (Ajax.BeginForm("ChangePassword", "Manage", null, options, new { @class = "form-horizontal", role = "form" }))
{
<div id="modalForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Change Password</h4>
</div>
<div class="modal-body">
@Html.AntiForgeryToken()
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.OldPassword, new { @class = "col-md-6 control-label" })
<div class="col-md-6">
@Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.NewPassword, new { @class = "col-md-6 control-label" })
<div class="col-md-6">
@Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-6 control-label" })
<div class="col-md-6">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Change Password</button>
</div>
</div>
}
动作控制器:
public ActionResult ChangePassword()
{
ChangePasswordViewModel cpvm = new ChangePasswordViewModel();
return PartialView(cpvm);
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
return Json(new { success = true });
}
// Failed
AddErrors(result);
return PartialView(model);
}
第一个问题的答案:- 只包含 JS 文件,即
Jquery Unobtrusive js
文件在您以模式打开的局部视图中然后它工作正常,有时这个问题出现在 asp.net mvc 的局部视图中。
只需将此 js 文件也包含在您的局部视图中:
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
或在局部视图中尝试此操作:
$.validator.unobtrusive.parse($("form"));
第二和第三个问题的答案:- 正如我在您的问题中看到的那样,您已经在使用
Ajax.BeginForm()
因此在提交表单时不应重新加载页面...只需检查您是否包含 jquery.unobtrusive- ajax.min.js 是否有js文件
并且还在
web.config
文件中添加以下代码:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
在讨论中加入我的观点,以防其他人需要similar解决方案。与原始问题不同,布局底部使用的添加验证文件对我有用。问题出在其他地方。
在显示模态后,在 ajax 请求中(在调用的成功部分)我遗漏了一些代码行。
public virtual PartialViewResult GetModal() { }
return PartialView("~/Views/Example/EditForm.cshtml", viewModel);
/* ajax call was made, the partial view is received */
// After successful call, insert the partial view form into the modal
$("#modalFormContainer").html(result);
// Show the modal
$('#myModal').modal('show');
// Apply frontend validation
$('#myModal').on('shown.bs.modal', function () {
jQuery.validator.unobtrusive.parse($(this)); // This fixed my problem.
})
我的问题是完全跳过了前端验证,直接将表单提交到后端(
Save
控制器中的 post 方法)。那行代码解决了这个问题。