MVC3 Validation with ComponentModel.DataAnnotations for UK d
本文关键字:for UK DataAnnotations ComponentModel Validation with MVC3 | 更新日期: 2023-09-27 18:30:55
我看到有一些类似的问题,但没有一个能解决我的问题。
我正在开发带有实体框架 4.3 的 MVC3 应用程序。我有一个英国日期字段,我计划允许用户使用 Jquery UI 日期选择器进行编辑(这要归功于这个博客,我得到了工作)。
幸运的是,此博客包含有关使用英国格式制作日期选择器的说明,但是,EF 验证仍然告诉我我需要输入有效的日期格式。巧妙地,它不会阻止我将日期提交给数据库,它只是不显眼的验证启动并显示消息。
目前我有以下数据注释:
[DataType(DataType.Date)]
public System.DateTime Module_Date { get; set; }
但我也尝试添加:
[DisplayFormat(DataFormatString="{0:dd/MM/yyyy}")]
完全没有效果。我希望有人有一个解决方案,因为我不喜欢关闭不显眼的验证来停止此错误消息。
谢谢
编辑
在回答@Iridio之后,我考虑添加模型绑定,事实上,从我读到的像这样的几篇帖子来看,这似乎是正确的做法,但我想出的没有效果。 这是我尝试过的:
public class DateTimeBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
var date = value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
return date;
}
}
在Global.asax.cs
文件的Application_Start()
方法中:
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeBinder());
是的,问题在于jquery验证脚本坚持使用US datefomat。我会克制自己不要对世界上大多数人使用 dd/mm/yyyy 这一事实进行适当的咆哮。
无论如何,最终我在对类似问题的答案的评论中找到了我的困境的答案,该问题的答案的作者善意地写了一篇关于他如何解决这个问题的博客文章。
基本上我使用了jquery全球化脚本,只是将文化设置为en-GB
。我应该提到,在他的博客中,他没有提到将位放在指定区域性的位置,所以我只是在页面中对全球化脚本的引用下插入脚本标签:
<script src="@Url.Content("~/Scripts/globalize.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/globalize.culture.en-GB.js")" type="text/javascript"></script>
<script type="text/javascript">
Globalize.culture("en-GB");
$.validator.methods.date = function (value, element) {
return this.optional(element) || Globalize.parseDate(value);
};
</script>
我相信mvc3框架附带的jquery ui datepicker的脚本版本(jquery-ui-1.8.11.js)中存在错误。
如果您以英国格式指定日期(如博客所述):
$(document).ready(function () {
$('.date').datepicker({dateFormat: "dd/mm/yy"});
});
然后 jquery-ui-1.8.11.js 似乎在验证日期时存在问题,并不断要求提供有效的英国日期(但验证似乎是随机的)。 如果您将日期格式更改为"mm/dd/yy",那么这个问题就会消失,但这对英国日期不利。
该问题已在该库的更高版本中解决,因此请下载最新版本(我相信在撰写本文时为 1.8.18)或参考 cdn:
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js" type="text/javascript"></script>
您必须为 DateTime 类型编写自己的 ModelBinder。
这是我为类似的问题编写的活页夹,但具有十进制类型(也许您将需要它)。 你应该掌握这个想法并使其适应你的需要
public class DecimalModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
然后在global.asax中注册您的活页夹,你就完成了
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
//Here you tell how to hendle the specific type
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
}
更新
在您澄清后,此答案应该会有所帮助
实际上我在这里找到了更好的解决方案....按 #fretje
覆盖 jquery 日期
我稍微修改了他/她的代码,以便它仍然可以采用日期格式,例如下面的 30 May 2012。
$(function () {
$.validator.addMethod(
"date",
function (value, element) {
//Added to validate dates like 31 May 2012
if (value.split('/').length === 1)
return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
var bits = value.match(/([0-9]+)/gi), str;
if (!bits)
return this.optional(element) || false;
str = bits[1] + '/' + bits[0] + '/' + bits[2];
return this.optional(element) || !/Invalid|NaN/.test(new Date(str));
},
"Please enter a date in the format dd/mm/yyyy"
);
$global.init();
});
我刚才遇到了这个问题,花了几个小时来追踪原因。我并不是说这是你的问题,但是在花了几个小时在所有事情上切换全球化等之后,我想我会在这里为任何像我这样挣扎的人发布这个问题。
无论如何,我项目中的问题实际上并不是我想象的那样。我用[DataAnnotationsExtentions.Date]
装饰了该物业,事实证明,在本地化方面(即,如果您想在英格兰 12 日之后的一天)在 chrome 中搞砸了客户端验证,尽管它似乎在其他浏览器中工作正常。一旦我删除它就可以工作
问题是,由于某种原因,如果你在文本框中放入一个名为"date"的类,Chrome 就会像这个博客中描述的那样变得疯狂。我遇到了同样的问题,我只是将类名更改为customDate,它就解决了。