C# · 12月 29, 2021

c# – 不引人注目的DateTime?验证MVC4

我将一个MVC3解决方案升级到了MVC4.迁移后,验证程序已损坏.

我的输入日期,如果我选择德语作为语言,是“20.03.2013”​​.我在MVC4中得到验证错误,但在MVC3中却没有.如果我将格式从“20.03.2013”​​更改为“20/03/2013”​​,它可以在MVC4中工作,但不能在MVC3中使用;-)

我将当前线程的UI文化设置为德语. ResX值的输出是正确的语言,所以我知道文化应该没有错误,只有站点本身.错误信息是英文,但网站是德文.

我认为这意味着验证器使用错误的UI文化.

这是我使用的代码.

[required(ErrorMessageResourceName = “Error_DepartureDate”,ErrorMessageResourceType = typeof(Resx.Query))]public DateTime? DepartureDate { get; set; }

我认为默认模型绑定器有问题,因为渲染的HTML看起来不错:

data-lang=”de” data-mindate=”3″ data-val=”true” data-val-required=”Bitte geben Sie das gewünschte Reisedatum des Hinflugs ein.” id=”DepartureDate” name=”DepartureDate” tabindex=”3″ type=”text” value=””

当您使用Visual Studio 2012(SP1安装)模板创建新的Mvc应用程序时,我将Jscript升级到发货的源.这没有影响.

我有一个CultureModelBinder读取Session中的当前文化,并使用一个小的帮助函数设置文化.

public static void UpdateThreadCulture(CultureInfo culture){ Thread.CurrentThread.CurrentUICulture = culture; }

文化模型binder是默认的binder.

ModelBinders.Binders.DefaultBinder = new CultureModelBinder();ModelBinders.Binders.Add(typeof(DateTime?),new DateTimeModelBinder());// and many,many more

也许在mvc4执行顺序中有什么变化导致问题?

更新:该项目使用.NET Framework 4.5作为目标.

更新2:

我有一个组合框,用户可以选择16种不同的语言,每个可能都有自己的格式.

例如.
DE-de – > DD.MM.YYYY;
en-en – > DD / MM / YYYY;
en-us – > MM / DD / YYYY

我只是提出了一个关于设定当前文化的提示,这里是证明它应该是正确的.当验证器失败时,这个代码没有被击中,它看起来像在客户端发生.

public class DateTimeModelBinder : IModelBinder { private LogService _log = new LogService(); public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { object result = null; ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueResult != null) { try { var stateHandler = new StateHandler(controllerContext.HttpContext.Session); result = valueResult.ConvertTo(typeof(DateTime?),stateHandler.Culture); } catch { try { result = valueResult.ConvertTo(typeof(DateTime?),CultureInfo.InvariantCulture); } catch (Exception ex) { _log.Error(“DateTimeModelBinder parse exception”,ex); _log.KeyValue(“AttemptedValue”,valueResult.AttemptedValue); } } } return result; } }

为了完整我的文化模型的粘合剂:

public class CultureModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { StateHandler stateHandler = new StateHandler(controllerContext.HttpContext.Session); Helper.UpdateThreadCulture(stateHandler.Culture); return base.BindModel(controllerContext,bindingContext); } }

更新:也许与这个问题有关系:
http://connect.microsoft.com/VisualStudio/feedback/details/705643/a-data-val-date-attribute-is-generated-for-time-fields-in-asp-net-mvc-4

更新:
阅读以下文章:
http://weblogs.asp.net/scottgu/archive/2010/06/10/jquery-globalization-plugin-from-microsoft.aspx

尝试了以下内容:

按以下顺序加载脚本:

/Scripts/jquery-1.8.3.min.js/Scripts/globalize.js/Scripts/cultures/globalize.cultures.js// and much more other scripts…

添加了通话.输出正确“DE”.

var currentLanguage = $(“#DepartureDate”).attr(“data-lang”); alert(currentLanguage); $.preferCulture(currentLanguage);

对验证者没有影响…

解决方法 关键是,Mvc3不会在客户端的所有日期验证是重点.你只是在服务器端设置文化….但你的文化设置在客户端根本没有反映,至少Mvc引擎不会自动执行.使用与英语不同的文化来处理客户端正确的日期和数字的唯一方法是使用一个能够解析所有文化中适当日期的javascript全球化库,并将客户端文化设置为服务器端文化,那么你必须正确地重新定义所有验证方法来使用全局化函数.
请阅读我的博客的这篇文章,阐明如何在客户端处理正确的全球化: http://www.dotnet-programming.com/post/2011/12/14/Globalization-Validation-and-DateNumber-Formats-in-AspNet-MVC.aspx

此外,请不要将CurrentCulture与CurrentUICulture混淆CurrentUICulture不会影响处理数字或日期的方式,而只会包含包含文化特定资源(如本地化字符串)的资源文件.

最后,由于模型绑定器是一个递归函数,因此在模型重建过程中被称为数百次,文化设置操作不是一个简单的变量设置操作,而是在模型绑定中设置文化是非常低效的,成本不可忽略.最好编写一个全局控制器过滤器来处理文化设置(我总是这样做),因此每个请求只执行一次操作