DataAnnotations
DataAnnotations是.Net(Core)框架内置的表单验证中间件,当前它的版本基本与.Net(Core)框架一致,.Net6框架最后一次更新的日期是:2022/4/13;版本号是:.NET 6.0.4(https://github.com/dotnet/core/releases/tag/v6.0.4),由于 .Net6框架是开源的DataAnnotations也应该是开源的,但我没有在.NET 6.0.4找到DataAnnotations。
DataAnnotations的定义和使用遵循了微软的一贯特征:使用简单(傻瓜)、封装严密(基本处于黑盒状态)、扩展简单,但可扩展性差,所以DataAnnotations表单验证的实现是学习和使用成本最低的。在一系列微软所定义的组件中,使用最为复杂的就是.Net(Core)框架,这极大可能是由于 .Net(Core)框架开源的因素,但这种使用的复杂性随着版本的迭代而降低,同时封装严密程序也随着版本的迭代而增加这从.Net(Core)框架1-6版本中的管道和依赖注入的配置实例就能直接直观的感受到这种不断改变的趋势。
模型类与DataAnnotations中的标记(过滤/令牌)属性相结合,来实现对表单输入操作进行验证,因此模型类与DataAnnotations之间的耦合程序是极高的,另外标记(过滤/令牌)虽然在VisualStudio开发中十分常见,但使用起来总是不如类和方法的调用或继承使用起来那么自然。
远程验证
远程验证是DataAnnotations表单输入验证的1个相对复杂的使用和实现,在.Net(Core)框架中有两种方法来实现表单的输入验证它们分别是:[AcceptVerbs("GET", "POST")]和JsonResult
1、使用远程验证需要先在WebDataAnnotations.Models.DefaultModel模型类的属性成员上定义相应的标记(过滤/令牌)
[Remote(action: "VerifyName", controller: "Home", AdditionalFields = nameof(Name))]
public string Name { get; set; }
[Remote(action: "VerifyEmail", controller: "Home", AdditionalFields = nameof(Email))]
public string Email { get; set; }
2、在WebDataAnnotations.Controllers.HomeController类中定义[AcceptVerbs("GET", "POST")]和JsonResult方法。
[AcceptVerbs("GET", "POST")]
/// 指定用户的姓名。
///
/// 【验证姓名】
///
/// 摘要:
/// 通过相应的参数实例,远程验证表单中所输入的用户名是否已经被注册。
///
///
/// 返回:
/// JSON编号格式的验证结果状态信息。
///
///
[AcceptVerbs("GET", "POST")]
public IActionResult VerifyName(string name)
{
if (name.Trim().Equals("zz", StringComparison.InvariantCultureIgnoreCase))
{
return Json($"该用户名:{name}已经被注册。");
}
return Json(true);
} }
JsonResult
/// 指定用户的电子邮箱。
///
/// 【验证电子邮箱】
///
/// 摘要:
/// 通过相应的参数实例,远程验证表单中所输入的电子邮箱是否已经被注册。
///
///
/// 返回:
/// JSON编码格式的验证结果状态信息。
///
///
public JsonResult VerifyEmail(string email)
{
if (email.Trim().Equals("admin@yourStore.com", StringComparison.InvariantCultureIgnoreCase))
{
return Json($"该电子邮箱:{email}已经被注册。");
}
return Json(true);
}
下拉框验证
1、对下拉框控件进行远程验证需要先在WebDataAnnotations.Models.DefaultModel模型类的属性成员上定义相应的标记(过滤/令牌)
[Required, Range(1, int.MaxValue, ErrorMessage = "必须选择1个城市")]
public int CityId { get; set; }
复选框验证 (MustBeTrue(自定义扩展标记(过滤/令牌)))
1、自定义MustBeTrueAttribute标记:
///
/// 【必须复选属性--类】
///
/// 摘要:
/// 通过该实体类及其方法成员实现,将页面表单中指定(复选框控件)属性与指定的验证标签及其样式进行绑定,为验证信息的呈现输出提供方法支撑。
///
///
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientModelValidator
{
#region 方法--私有/保护
/// 用于存储键/值对项的字典实例。
/// 指键的常量字符串。
/// 指定键所对应的字符串类型的值。
///
/// 【拼接属性?】
///
/// 摘要:
/// 通过相应的参数实例,获取1个值false(包含)/true(不包含),该值指示字典实例中是否不包含1个指定的键/值对项,如果不包含则把该键/值对项存储到字典实例中。
///
///
/// 返回:
/// 1个值false(包含)/true(不包含)。
///
///
private bool MergeAttribute(
IDictionary
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
#endregion
#region 方法--接口实现--IClientModelValidator
/// 客户端模型验证上下文实例。
///
/// 【添加验证】
///
/// 摘要:
/// 通过相应的参数实例,将页面表单中指定属性与指定的验证标签及其样式进行绑定,为验证信息的呈现输出提供方法支撑。
///
///
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMsg = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-mustbetrue", errorMsg);
}
#endregion
#region 方法--覆写--ValidationAttribute
/// 1个指定的泛型实例的实例值。
///
/// 【有效?】
///
/// 摘要:
/// 通过相应的参数实例,获取1个值false(不为真)/true(为真),该值指示1个指定的泛型实例的实例值是否为真(true)。
///
///
/// 返回:
/// 1个值false(不为真)/true(为真)
///
///
public override bool IsValid(object value)
{
return value != null && (bool)value == true;
}
#endregion
}
2、 @*自定义验证信息呈现标签*@
3、自定义Jquery验证代码
section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
$.validator.addMethod("MustBeTrue",
function (value, element, parameters) {
return element.checked;
});
$.validator.unobtrusive.adapters.add("MustBeTrue", [], function (options) {
options.rules.mustbetrue = {};
options.messages["MustBeTrue"] = options.message;
});
}
注意:
自定义Jquery验证代码必须依赖于:“jquery.validate.min.js”和“jquery.validate.unobtrusive.min.js”,才能正常执行自定义Jquery验证代码,由于_ValidationScriptsPartial.cshtml页面对“jquery.validate.min.js”和“jquery.validate.unobtrusive.min.js”进行了预先的绑定,所以


