一般的,我们在添加信息时,可以通过ModelState快速实现模型验证
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(UserInfo userInfo)
{
if (ModelState.IsValid)
{
db.UserInfo.Add(userInfo);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(userInfo);
}
效果,自动验证
但是,改用ajax异步操作,就无法通过模型自动验证了
ASP.NET实现ajax异步,要添加jquery.unobtrusive-ajax.js文件,只需在NuGet搜索下载即可
添加引用
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
在视图中,需要将@using (Html.BeginForm()) 改为 @using (Ajax.BeginForm()),
@using (Ajax.BeginForm("VerifyUser", "UserInfo", new AjaxOptions() { OnSuccess = "afterCreate" }, new { @class = "form-signin" }))
然后点击确定按钮提交表单,却一直无反应,试过很多次还是无反应
分析
后面,想着想着才知道这是操作,就是视图局部更新,而上面同步的操作,当模型验证失败时通过在整个视图添加错误信息到达验证模型的效果,而异步操作就是局部更新,当然不会执行整个视图的更新,只能通过js代码执行更新操作
当执行后台方法VerifyUser后执行afterLogin方法
对Create方法进行改造
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(UserInfo userInfo)
{
if (ModelState.IsValid)
{
db.UserInfo.Add(userInfo);
db.SaveChanges();
return Content("ok");
}
return Content("添加失败");
}
当后台只有返回ok时,才执行跳转,否则则弹框提示
<script type="text/javascript">
function afterCreate(data) {
if (data == "ok")
window.location.href = "@Url.Action("Index","UserInfo")";
else
alert(data);
}
</script>
完成
2020-03-08
后面在B站看MVC博客项目实战时,学习到可以直接在后台添加异步操作,直接在Action改为异步操作即可
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(UserInfo userInfo)
{
if (ModelState.IsValid)
{
db.UserInfo.Add(userInfo);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(userInfo);
}
视图中的表单还是用@using (Html.BeginForm())即可
2020-03-10
使用上面的方法,发现如果是自己添加的错误,即是
public async Task<ActionResult> Create(UserInfo userInfo)
{
if (ModelState.IsValid == true)
{
//是否存在相同用户名
if (await UserInfoService.GetEntities(u => u.Name == userInfo.Name).FirstOrDefaultAsync() != null)
{
ModelState.AddModelError("Name", "存在相同用户名");
ViewBag.Sexs = GetSexs();
return View(userInfo);
}
UserInfoService.Add(userInfo);
return RedirectToAction("Index");
}
ViewBag.Sexs = GetSexs();
return View(userInfo);
}
这样无法到达异步效果,提示“存在相同用户”时,界面还是会全部刷新
还是将操作改为非异步
public ActionResult Create(UserInfo userInfo)
{
if (ModelState.IsValid == true)
{
//是否存在相同用户名
if (UserInfoService.GetEntities(u => u.Name == userInfo.Name).FirstOrDefault() != null)
{
return Content("存在相同用户名");
}
UserInfoService.Add(userInfo);
return Content("ok");
}
return Content(ModelState.GetErrorMessage());
}
使用异步表单
@using (Ajax.BeginForm("Create", "UserInfo", new AjaxOptions() { OnSuccess = "afterCreate" }))
添加js脚本
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script type="text/javascript">
function afterCreate(data) {
if (data == "ok") {
$(location).attr('href', '/UserInfo/Index');
}
else {
//弹框提示
$("#MessageBox-info-text").text(data);
$("#MessageBox-info").modal("show");
}
}
</script>
在这里注意去除@Scripts.Render("~/bundles/jqueryval")脚本,不然还是会使用上面的脚本验证
@Scripts.Render("~/bundles/jqueryval")中,实际起作用的就是下面两个脚本
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
其实可以将@Scripts.Render("~/bundles/jqueryval")和 <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>同时使用
先验证模型自身的状态,在验证业务逻辑的正确性,一个是直接在页面显示,一个是弹框提示,当然也可以通过js统一提示