我的输入日期,如果我选择德语作为语言,是“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://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...
var currentLanguage = $("#DepartureDate").attr("data-lang"); alert(currentLanguage); $.preferCulture(currentLanguage);
对验证者没有影响…
解决方法
请阅读我的博客的这篇文章,阐明如何在客户端处理正确的全球化: http://www.dotnet-programming.com/post/2011/12/14/Globalization-Validation-and-DateNumber-Formats-in-AspNet-MVC.aspx
此外,请不要将CurrentCulture与CurrentUICulture混淆CurrentUICulture不会影响处理数字或日期的方式,而只会包含包含文化特定资源(如本地化字符串)的资源文件.
最后,由于模型绑定器是一个递归函数,因此在模型重建过程中被称为数百次,文化设置操作不是一个简单的变量设置操作,而是在模型绑定中设置文化是非常低效的,成本不可忽略.最好编写一个全局控制器过滤器来处理文化设置(我总是这样做),因此每个请求只执行一次操作