我的ViewModel中有一个DateTime MyDate
类型的属性。我想确保用户只在特定格式(dd.mm.yyyy)的文本框中输入Date部分,并尝试以下属性:
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode=true)]
[RegularExpression(@"^(([0-2]\d|[3][0-1])\.([0]\d|[1][0-2])\.[2][0]\d{2})$",
ErrorMessage="Failed...")]
public DateTime MyDate { get; set; }
HttpPost的控制器操作签名如下所示:
[HttpPost]
public ActionResult Edit(int id, MyViewModel viewModel)
{
// MyViewModel contains the MyDate property ...
// ...
if (ModelState.IsValid)
{
// ...
}
// ...
}
在Razor视图中,我尝试了以下两种方式:
@Html.TextBoxFor(model => model.MyDate)
@Html.EditorFor(model => model.MyDate)
它无法正常工作。结果是:
MyDate
属性已正确填充,并在viewModel
中输入了传递给操作的日期。所以模型绑定似乎正在发挥作用。DisplayFormat
属性仅由EditorFor
尊重,但不受TextBoxFor
尊重。 TextBoxFor
显示“dd.mm.yyyy hh:mm:ss”问题:
我可以在不属于RegularExpressionAttribute
的媒体上申请string
吗?如果允许,如何在服务器端对{1}}之类的非字符串属性评估reg ex?类似于DateTime
与reg ex相比? (它会解释验证失败,因为ToString将返回一个包含时间部分的字符串,该字符串不会传递正则表达式。)
MyDate.ToString()
属性通常仅由DisplayFormat
尊重,而不是EditorFor
吗?
如何进行日期验证?
答案 0 :(得分:10)
不要使用正则表达式来验证日期,它们只是被忽略。
文化差异可能是问题的根源。客户端验证使用浏览器的文化来验证日期。因此,例如,如果将其配置为en-US
,则预期格式为MM/dd/yyyy
。如果您的服务器配置为使用fr-FR
,则预期的格式为dd/MM/yyyy
。
您可以使用web.config中的<globalization>
元素来设置服务器端文化。您可以使用与客户端相同的文化来配置它:
<globalization culture="auto" uiCulture="auto"/>
Hanselman在ASP.NET MVC中有关于全球化和本地化的nice blog post。
答案 1 :(得分:4)
我现在扔掉了RegularExpression
。它似乎不适合DateTime
类型的属性。然后我为DateTime和可为空的DateTime创建了一个新的验证属性:
[AttributeUsage(AttributeTargets.Property, Inherited = false,
AllowMultiple = false)]
public sealed class DateOnlyAttribute : ValidationAttribute
{
public DateOnlyAttribute() :
base("\"{0}\" must be a date without time portion.")
{
}
public override bool IsValid(object value)
{
if (value != null)
{
if (value.GetType() == typeof(DateTime))
{
DateTime dateTime = (DateTime)value;
return dateTime.TimeOfDay == TimeSpan.Zero;
}
else if (value.GetType() == typeof(Nullable<DateTime>))
{
DateTime? dateTime = (DateTime?)value;
return !dateTime.HasValue
|| dateTime.Value.TimeOfDay == TimeSpan.Zero;
}
}
return true;
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture,
ErrorMessageString, name);
}
}
用法:
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode=true)]
[DateOnly]
public DateTime MyDate { get; set; }
它不提供客户端验证。在服务器端,验证依赖于模型绑定(以确保输入的字符串完全可转换为DateTime
)。如果用户输入了午夜以外的时间部分,则DateOnly
属性会启动,并且会收到警告,指出只应输入日期。