自定义验证在服务器端有效,但在客户端无效 asp mvc 5
Custom validation works server side but not client side asp mvc 5
我有一个自定义验证 class 来验证日期。它适用于服务器端但不适用于客户端。我无法触发 jquery 方法来进行检查。我想我可能有一些东西与适配器或验证器连接不正确。
P.S。我可以让非自定义客户端验证工作(例如 [必需]),而不是我的自定义验证
查看模型
public class HomePageViewModel
{
[Required]
public string SearchQuery { get; set; }
[DisplayName("Date")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[ClassDate(ErrorMessage = "Class date must be today or later.")]
public DateTime ClassDate { get; set; }
}
验证class.
public class ClassDateAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null) // ok, just use todays date day
{
return true;
}
DateTime toValidate = (DateTime) value;
if (toValidate.Day < DateTime.Now.Day) // if they are looking for classes in the past
{
return false;
}
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
ControllerContext context)
{
var classDateRule = new ModelClientValidationRule();
classDateRule.ErrorMessage = "test error message";
classDateRule.ValidationType = "classdate";
yield return classDateRule;
}
}
Javascript代码。
$(function () {
$(".datefield").datepicker();
var now = new Date();
var day = ("0" + now.getDate()).slice(-2);
var month = ("0" + (now.getMonth() + 1)).slice(-2);
var today = (month) + "/" + (day) + "/" + now.getFullYear();
$('.datefield').val(today);
$.validator.unobtrusive.adapters.addSingleVal("classdate");
$.validator.addMethod("classdate", function(value) {
if (value) {
//do something to test date here
//if date is today or later
return true;
}
return false;
});
});
这是我认为的元素。
@Html.TextBoxFor(model => model.ClassDate, new { @class = "datefield form-control", @id = "ClassDate", @type = "date", name = "ClassDate" })
@Html.ValidationMessageFor(model => model.ClassDate, "", new { @class = "text-danger" })
您没有获得客户端验证的主要问题是您使用了 $.validator.unobtrusive.adapters.addSingleVal("classdate");
。 addSingleVal()
用于验证模型中的另一个 属性。需要 $.validator.unobtrusive.adapters.addBool("classdate");
由于您使用的是 jQueryUI 日期选择器,因此您可以使用
来防止选择小于今天的日期
$(.datefield).datepicker({
minDate: 0
});
你们中的许多人在这里编写的代码毫无意义(请参阅下面的旁注),应该类似于
属性定义
[DisplayName("Date")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
[NotLessThanToday]
public DateTime ClassDate { get; set; }
验证属性
public class NotLessThanTodayAttribute : ValidationAttribute, IClientValidatable
{
private const string _DefaultErrorMessage = "The property {0} cannot be less than todays date";
public NotLessThanTodayAttribute() : base(_DefaultErrorMessage)
{
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
return ValidationResult.Success; // ??
}
DateTime date = DateTime.Today;
if (DateTime.TryParse((string)value, out date))
{
if (date < DateTime.Today)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
else
{
// not a valid date
}
return base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "notlessthantoday"
};
return new[] { clientValidationRule };
}
}
脚本
$.validator.addMethod("notlessthantoday", function (value, element, params) {
if (!this.optional(element)) {
var date = new Date(value);
var today = new Date();
return date > today;
}
return true; // ??
});
$.validator.unobtrusive.adapters.addBool("notlessthantoday");
旁注
ApplyFormatInEditMode = true
与
[DataType(DataType.Date)]
和 @Html.EditorFor()
渲染
浏览器 HTML5 日期选择器。这里没有必要,如果你这样做了
使用它,格式字符串需要是 "{0:yyyy-MM-dd}"
(ISO
格式)
- 您当前的验证属性只检查日期
比今天少。
if (toValidate.Day < DateTime.Now.Day)
意思是 1/1/2016
有效(1
小于 24
)。
- 脚本
var now = new Date(); ..... $('.datefield').val(today);
没有意义并覆盖模型中的值(用户输入
日期,您 post 和 return 视图和您的代码重置日期
回到今天的价值!)。如果你想显示今天的日期,那么
在将值传递给视图之前在模型中设置值
(model.ClassDate = Datetime.Today;
)
- 您在助手中设置(或尝试)以下属性:
@id="ClassDate", @type="date", name="ClassDate"
。 html 助手
无论如何将 id
属性设置为 id="ClassDate"
。这
type="date"
不是必需的(那是为了让浏览器 HTML5
datepicker) 并设置 name
属性
什么都没有(幸运的是它不起作用,因为你试图给它
它是 "ClassDate" 以外的名称,绑定会失败)
document.ready...
1) 整个网页加载完成后执行。
2) 通常,用于初始化 dom 元素上的事件(如 .click、.change、.select)。这是有道理的,因为您通常不能将事件附加到 dom 尚未加载的元素。
3) 一般情况下,函数不会进入document.ready。这是有道理的,因为函数通常由事件调用。
当然,凡事都有例外,但这些都是很好的经验法则。
我有一个自定义验证 class 来验证日期。它适用于服务器端但不适用于客户端。我无法触发 jquery 方法来进行检查。我想我可能有一些东西与适配器或验证器连接不正确。 P.S。我可以让非自定义客户端验证工作(例如 [必需]),而不是我的自定义验证
查看模型
public class HomePageViewModel
{
[Required]
public string SearchQuery { get; set; }
[DisplayName("Date")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[ClassDate(ErrorMessage = "Class date must be today or later.")]
public DateTime ClassDate { get; set; }
}
验证class.
public class ClassDateAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null) // ok, just use todays date day
{
return true;
}
DateTime toValidate = (DateTime) value;
if (toValidate.Day < DateTime.Now.Day) // if they are looking for classes in the past
{
return false;
}
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
ControllerContext context)
{
var classDateRule = new ModelClientValidationRule();
classDateRule.ErrorMessage = "test error message";
classDateRule.ValidationType = "classdate";
yield return classDateRule;
}
}
Javascript代码。
$(function () {
$(".datefield").datepicker();
var now = new Date();
var day = ("0" + now.getDate()).slice(-2);
var month = ("0" + (now.getMonth() + 1)).slice(-2);
var today = (month) + "/" + (day) + "/" + now.getFullYear();
$('.datefield').val(today);
$.validator.unobtrusive.adapters.addSingleVal("classdate");
$.validator.addMethod("classdate", function(value) {
if (value) {
//do something to test date here
//if date is today or later
return true;
}
return false;
});
});
这是我认为的元素。
@Html.TextBoxFor(model => model.ClassDate, new { @class = "datefield form-control", @id = "ClassDate", @type = "date", name = "ClassDate" })
@Html.ValidationMessageFor(model => model.ClassDate, "", new { @class = "text-danger" })
您没有获得客户端验证的主要问题是您使用了 $.validator.unobtrusive.adapters.addSingleVal("classdate");
。 addSingleVal()
用于验证模型中的另一个 属性。需要 $.validator.unobtrusive.adapters.addBool("classdate");
由于您使用的是 jQueryUI 日期选择器,因此您可以使用
来防止选择小于今天的日期$(.datefield).datepicker({
minDate: 0
});
你们中的许多人在这里编写的代码毫无意义(请参阅下面的旁注),应该类似于
属性定义
[DisplayName("Date")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
[NotLessThanToday]
public DateTime ClassDate { get; set; }
验证属性
public class NotLessThanTodayAttribute : ValidationAttribute, IClientValidatable
{
private const string _DefaultErrorMessage = "The property {0} cannot be less than todays date";
public NotLessThanTodayAttribute() : base(_DefaultErrorMessage)
{
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
return ValidationResult.Success; // ??
}
DateTime date = DateTime.Today;
if (DateTime.TryParse((string)value, out date))
{
if (date < DateTime.Today)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
else
{
// not a valid date
}
return base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "notlessthantoday"
};
return new[] { clientValidationRule };
}
}
脚本
$.validator.addMethod("notlessthantoday", function (value, element, params) {
if (!this.optional(element)) {
var date = new Date(value);
var today = new Date();
return date > today;
}
return true; // ??
});
$.validator.unobtrusive.adapters.addBool("notlessthantoday");
旁注
ApplyFormatInEditMode = true
与[DataType(DataType.Date)]
和@Html.EditorFor()
渲染 浏览器 HTML5 日期选择器。这里没有必要,如果你这样做了 使用它,格式字符串需要是"{0:yyyy-MM-dd}"
(ISO 格式)- 您当前的验证属性只检查日期
比今天少。
if (toValidate.Day < DateTime.Now.Day)
意思是1/1/2016
有效(1
小于24
)。 - 脚本
var now = new Date(); ..... $('.datefield').val(today);
没有意义并覆盖模型中的值(用户输入 日期,您 post 和 return 视图和您的代码重置日期 回到今天的价值!)。如果你想显示今天的日期,那么 在将值传递给视图之前在模型中设置值 (model.ClassDate = Datetime.Today;
) - 您在助手中设置(或尝试)以下属性:
@id="ClassDate", @type="date", name="ClassDate"
。 html 助手 无论如何将id
属性设置为id="ClassDate"
。这type="date"
不是必需的(那是为了让浏览器 HTML5 datepicker) 并设置name
属性 什么都没有(幸运的是它不起作用,因为你试图给它 它是 "ClassDate" 以外的名称,绑定会失败)
document.ready...
1) 整个网页加载完成后执行。
2) 通常,用于初始化 dom 元素上的事件(如 .click、.change、.select)。这是有道理的,因为您通常不能将事件附加到 dom 尚未加载的元素。
3) 一般情况下,函数不会进入document.ready。这是有道理的,因为函数通常由事件调用。
当然,凡事都有例外,但这些都是很好的经验法则。