Shr*_*van 7 editortemplates data-annotations unobtrusive-validation asp.net-mvc-3
我是ASP.Net MVC 3的新手,在尝试为我自己创建的用于以自定义方式显示日期的编辑器模板实现客户端不显眼的验证时遇到了一些问题.
UI
我需要以三个texbox UI格式显示日期

我已经建立了一个EditorTemplate,用于显示三个部分的日期
@model DateTime?
<table class="datetime">
<tr>
<td>@Html.TextBox("Day", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td>
<td class="separator">/</td>
<td>@Html.TextBox("Month", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td>
<td class="separator">/</td>
<td>@Html.TextBox("Year", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td>
</tr>
<tr>
<td class="label">dd</td>
<td/>
<td class="label">mm</td>
<td/>
<td class="label">yyyy</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
模型
I必须在此结构中将出生日期字段绑定到此属性,该字段是我的模型的子对象中的属性
MyModel
--> MySubModel
--> DateOfBirth
public class MySubModel
{
...
[DataType(DataType.Date)]
[Display(Name = "Date of birth")]
[DateTimeClientValidation()]
public DateTime DateofBirth { get; set; }
...
}
Run Code Online (Sandbox Code Playgroud)
客户端验证
我已经提出了一个自定义验证属性,它实现了IClientValidatable
public class DateTimeClientValidationAttribute : ValidationAttribute, IClientValidatable
{
...
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
List<ModelClientValidationRule> clientRules = new List<ModelClientValidationRule>();
//Combined date should be valid
ModelClientValidationRule validDateRule = new ModelClientValidationRule
{
ErrorMessage = "Please enter a valid date.",
ValidationType = "validdate"
};
validDateRule.ValidationParameters.Add("dayelement", metadata.PropertyName + ".Day");
validDateRule.ValidationParameters.Add("monthelement", metadata.PropertyName + ".Month");
validDateRule.ValidationParameters.Add("yearelement", metadata.PropertyName + ".Year");
clientRules.Add(validDateRule);
return clientRules;
}
...
}
Run Code Online (Sandbox Code Playgroud)
我试图在这里向客户端验证元素发出日,月和年文本框的元素名称,以便稍后我将编写客户端jquery验证方法和适配器,这将消耗这些元素并在客户端进行验证.
现在查看,要使用此编辑器模板,我将查看以下行
@model MyModel
...
<tr>
<td class="editor-label">
@Html.LabelFor(m => m.MySubModel.DateofBirth)
</td>
<td class="editor-field">
@Html.EditorFor(m => m.MySubModel.DateofBirth)
@Html.ValidationMessageFor(m => m.MySubModel.DateofBirth)
</td>
</tr>
...
Run Code Online (Sandbox Code Playgroud)
在视图中添加了所有相关的jquery验证文件作为参考
问题
感谢您耐心地阅读所有这些以及答案
Shr*_*van 10
经过一番努力,我让控制工作,如果对那里的任何人都有帮助,那就投入使用.
第一点是将控件定义为
@model DateTime?
<table class="datetime">
<tr>
<td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td>
<td class="separator">/</td>
<td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td>
<td class="separator">/</td>
<td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td>
</tr>
<tr>
<td class="label">dd</td>
<td/>
<td class="label">mm</td>
<td/>
<td class="label">yyyy</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
确保您将空字符串作为名称提供给所有三个文本框,这会强制MVC框架为客户端中的所有三个文本框生成与Model DateofBirth对应的相同名称.此外,将为列表中的第一个文本框生成不显眼的javascript验证参数,因为它是具有模型名称的编辑控件的第一个出现.
在客户端,任何这些文本框上的任何事件都会触发所有相关的验证事件,因为所有这3个文本框都具有相同的名称.
除了必需的常规验证之外,....我们必须编写一个自定义客户端验证例程,它将组合所有这三个值并检查组合值是否构成有效日期.这可以通过Jeff给出的答案来实现.
好吧,好几件事.首先 - 如果可能的话,不要将日期分成三个字段.只需将其设置为具有一些验证的单个字段并且可能是jQueryUI的DatePicker,您将为自己省去一个令人头痛的世界.
接下来,在DateTimeClientValidationAttribute内的自定义属性代码中,您实际上从未通过实现IsValid来检查日期是否有效:
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
...
// Put date parts together and check is valid...
if (DateTime.TryParse(year+"/"+month+"/"+day, out dateResult))
return ValidationResult.Success;
// Not valid
return new ValidationResult(String.Format(ErrorMessageString,
validationContext.DisplayName));
}
Run Code Online (Sandbox Code Playgroud)
接下来,您将不得不创建一个不显眼的验证适配器和一个jQuery验证器方法,它将params放在一起并尝试解析日期:
jQuery.validator.unobtrusive.adapters.add(
'validdate', // notice this is coming from how you named your validation rule
['dayelement'],
['monthelement'],
['yearelement']
function (options) {
options.rules['datepartcheck'] = options.params;
options.messages['datepartcheck'] = options.message;
}
);
jQuery.validator.addMethod('datepartcheck', function (value, element, params) {
var year = params[2];
var month = params[1];
var day = params[0];
var birthDate = year + '/' + month-1 + '/' + day;
var isValid = true;
try {
// datepicker is a part of jqueryUI.
// include it and you can take advantage of .parseDate:
$.datepicker.parseDate('yy/mm/dd', birthDate);
}
catch (error) {
isValid = false;
}
return isValid;
}, '');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7441 次 |
| 最近记录: |