【问题标题】:MVC3 Validation with ComponentModel.DataAnnotations for UK date format (also using jquery ui datepicker)MVC3 Validation with ComponentModel.DataAnnotations for UK date format(也使用jquery ui datepicker)
【发布时间】:2012-04-13 08:42:12
【问题描述】:

我看到有一些类似的问题,但没有一个能解决我的问题。

我正在使用 Entity Framework 4.3 开发 MVC3 应用程序。我有一个英国日期字段,我计划允许用户使用 Jquery UI 日期选择器进行编辑(感谢this blog,我开始工作了)。

对我来说幸运的是,此博客包含有关使用英国格式制作日期选择器的说明,但是,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());

【问题讨论】:

  • 我相信您指的是 System.ComponentModel.DataAnnotations 而不是 EntityFramework 数据注释?如果您关注博客,那么您是否在客户端脚本中指定数据格式{dateFormat: "dd/mm/yy"}?如果是这样,您使用的是什么版本的 jquery ui 脚本?
  • 哦,你说得很对,我正在使用 ComponentModel 的。我习惯在上一个项目中使用 EF 的。将更新。我使用的是 jquery ui 1.8.7,但我已根据您在下面的回答更新到最新版本,但无济于事
  • 哦,是的,我指定了{dateFormat:"dd/mm/yyyy"}
  • 澄清一下,是客户端验证(而不是服务器端验证)抱怨日期格式不正确? 验证仍然告诉我需要输入有效的日期格式。我走这条路的原因是我这周在同一个博客上遇到了这个问题。
  • 是的,没错,我应该更清楚。它是客户端验证。创建页面的默认值设置为今天的日期(13/4/2012,对美国无效),如果您不更改它并单击保存,它将很乐意将其添加到数据库中

标签: c# asp.net-mvc-3 entity-framework validation data-annotations


【解决方案1】:

是的,问题在于 jquery 验证脚本坚持使用美国日期格式。不过,我会克制自己不要对世界上大多数人使用 dd/mm/yyyy 的事实进行适当的咆哮。

无论如何,最终我在对类似question 的回答的评论中找到了解决我的困境的答案,该问题的作者请写了blog post 关于他如何解决这个问题。

基本上我使用了jquery globalize script,并将文化设置为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>

【讨论】:

  • 真的没有必要为了让英国日期生效而费尽心思!但感谢我被困在这个上的信息。只是希望 jQuery 尽快添加一种更优雅的方式来做到这一点。那个脚本 globalize.js(讽刺地用 z 拼写 :))文件非常大。
  • @PaulJohnson 我同意,我不应该这样做,事实上它对于很多情况都不是一个很好的解决方案,因为它总是强制使用英国格式日期。
  • 我已经搜索了两天来解决这个问题,由于你提到的原因,手指最终指向了 JQuery。这个修复对我来说非常有效 - 尽管实现它的最简单方法是使用 nuget 添加 jquery-globalise 包 - 如果你这样做,那么脚本位置将变为 /Scripts/globalize/globalize.js 和 /Scripts/ globalize/culture/globalize.culture.en-GB.js
【解决方案2】:

我认为 mvc3 框架 (jquery-ui-1.8.11.js) 附带的 jquery ui datepicker 的脚本版本存在错误。

如果您以英国格式指定日期(正如博客所述):

$(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>

【讨论】:

  • 看起来我使用的是稍旧的版本(1.8.7),所以换成了新版本,没有任何区别。不过谢谢
【解决方案3】:

您必须为 DateTime 类型编写自己的 ModelBinder。

这是我为类似问题编写的活页夹,但使用的是 Decimal 类型(也许你会需要它)。你应该掌握这个想法并根据你的需要进行调整

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 中注册你的 binder 就完成了

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());
}

更新

经过您的澄清this answer 应该会有所帮助

【讨论】:

  • 尝试了类似的方法,但无法成功,我已经尝试更新了我的问题
  • 更新了在客户端验证中使用 globalize 的答案
【解决方案4】:

实际上我在这里找到了更好的解决方案.... by #fretje

Override jquery date

我已经稍微修改了他/她的代码,以便它仍然可以采用日期格式,例如下面的 2012 年 5 月 30 日。

$(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();
});

【讨论】:

    【解决方案5】:

    我刚刚遇到了这个问题,花了我几个小时才找到原因。我不是说这是你的问题,但在花了几个小时在所有事情上切换全球化等之后,我想我会把这个问题贴在这里给像我一样挣扎的人。

    无论如何,我的项目中的问题实际上并不是我想的那样。我用[DataAnnotationsExtentions.Date] 装饰了该物业,事实证明,当涉及到本地化时(即如果你想在英格兰的 12 日之后的一天),它会在 chrome 中搞砸客户端验证,尽管它似乎在其他地方工作得很好浏览器。一旦我删除它就可以了

    【讨论】:

      【解决方案6】:

      问题在于,由于某种原因,如果您在文本框中放置了一个名为“date”的类,Chrome 就会像this blog 中所述的那样发疯。我有同样的问题,我只是将类名更改为 customDate 并解决了。

      【讨论】:

      • 请不要发布仅链接的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多