原文:MVC验证11-对复杂类型使用jQuery异步验证本篇体验使用"jQuery结合Html.BeginForm()"对复杂类型属性进行异步验证。与本篇相关的"兄弟篇"包括:
MVC验证08-jQuery异步验证
MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证
MVC验证10-到底用哪种方式实现客户端服务端双重异步验证
准备工作
□ js方面:
1、jquery的某个版本
2、jquery.validate.js
3、jquery.validate.unobtrusive.js
□ Web.config:
<appSettings>
...
<add key="ClientValidationEnabled" value="http://www.mamicode.com/true" />
<add key="UnobtrusiveJavaScriptEnabled" value="http://www.mamicode.com/true" />
</appSettings>
□ View Model
public class User
{
[Required]
[StringLength(8, MinimumLength = 3)]
[ValidUserName(ErrorMessage = "用户名必须是darren")]
[Display(Name = "用户名")]
public string UserName { get; set; }
[Required]
[StringLength(8, MinimumLength = 3)]
[Display(Name = "别名")]
public string DisplayName { get; set; }
}
public class ValidationModel
{
public User User { get; set; }
public List<User> Users { get; set; }
}
<style type="text/css">.csharpcode, .csharpcode pre{ font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em;}.csharpcode .lnum { color: #606060; }</style>□ 自定义特性
public class ValidUserNameAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
//同时满足2个条件返回true
return (value != null && value.ToString() == "darren");
}
}
<style type="text/css">.csharpcode, .csharpcode pre{ font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em;}.csharpcode .lnum { color: #606060; }</style>
HomeController无论是否验证成功都返回部分视图
using System.Web.Mvc;
using ValidComplex.Models;
namespace ValidComplex.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new ValidationModel());
}
public ActionResult ValidUser(ValidationModel validationModel)
{
return PartialView(!ModelState.IsValid ? "_Form" : "_Success", validationModel);
}
}
}
<style type="text/css">.csharpcode, .csharpcode pre{ font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em;}.csharpcode .lnum { color: #606060; }</style>
Index.cshtml视图
注意:
※ 从控制器返回的部分视图被加载到Index.cshtml视图中id为FormContainer的div中。$("#FormContainer").html(data);
※ 表单提交不应该这样写:$("form").on("submit", function (event),因为对动态生成内容无效。
@model ValidComplex.Models.ValidationModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@DateTime.Now: Index.cshtml视图被渲染
<div id="FormContainer">
@Html.Partial("_Form")
</div>
@section scripts
{
<script type="text/javascript">
$(function() {
$(‘#FormContainer‘).on("submit", "form",function(event){
//$("form").on("submit", function (event) {
event.preventDefault();
var form = $(this);
$.ajax({
url: form.attr(‘action‘),
type: "POST",
data: form.serialize(),
success: function (data) {
$("#FormContainer").html(data);
$.validator.unobtrusive.parse("form");
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error ‘" + jqXhr.status + "‘ (textStatus: ‘" + textStatus + "‘, errorThrown: ‘" + errorThrown + "‘)");
},
});
});
});
</script>
}
<style type="text/css">.csharpcode, .csharpcode pre{ font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em;}.csharpcode .lnum { color: #606060; }</style>
_Form.cshtml部分视图
展开@model ValidComplex.Models.ValidationModel@DateTime.Now: Partial/_Form.cshtml视图被渲染<hr/><style type="text/css"> p { margin: 3px; } h6 { margin: 3px; }</style>@using (Html.BeginForm("ValidUser", "Home")){ <h6>输入用户信息</h6> <p> @Html.LabelFor(m => m.User.UserName): @Html.EditorFor(m => m.User.UserName) @Html.ValidationMessageFor(m => m.User.UserName) </p> <p> @Html.LabelFor(m => m.User.DisplayName): @Html.EditorFor(m => m.User.DisplayName) @Html.ValidationMessageFor(m => m.User.DisplayName) </p> <h6>输入多个用户信息</h6> for (var i = 0; i <= 1; i++) { <h6>用户 @i</h6> <p> @Html.LabelFor(m => m.Users[i].UserName): @Html.EditorFor(m => m.Users[i].UserName) @Html.ValidationMessageFor(m => m.Users[i].UserName) </p> <p> @Html.LabelFor(m => m.Users[i].DisplayName): @Html.EditorFor(m => m.Users[i].DisplayName) @Html.ValidationMessageFor(m => m.Users[i].DisplayName) </p> } <input type="submit" value="提交" />}
_Success.cshtml部分视图
@model ValidComplex.Models.ValidationModel
<p><strong>验证通过 :)</strong></p>
<p>
用户名: ‘@Model.User.UserName‘<br />
别名: ‘@Model.User.DisplayName‘<br />
用户1的用户名: ‘@Model.Users[0].UserName‘<br />
用户1的别名: ‘@Model.Users[0].DisplayName‘<br />
用户2的用户名: ‘@Model.Users[1].UserName‘<br />
用户2的别名: ‘@Model.Users[1].DisplayName‘
</p>
<style type="text/css">.csharpcode, .csharpcode pre{ font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em;}.csharpcode .lnum { color: #606060; }</style>效果:
没有填写,提交,报错:
字数长度不符合,UserName不符合,提交,报错:
自定义特性,通过服务端验证后报错:
填写正确,提交,通过:
总结
可见,如果要对包含复杂类型属性(类属性、集合属性等)的View Model进行验证,只需要对简单类(比如这里的User)设置各种验证规则。