不引人注意的DateTime?在MVC4中验证

Nic*_*ckD 11 c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我将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="" 

我将Jscript升级到使用Visual Studio 2012(已安装SP1)模板创建新Mvc应用程序时发布的源代码.这没有任何影响.

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

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

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净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);

对验证者没有影响......

Fra*_*ese 10

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

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

最后,在模型绑定器中设置文化是非常不合理的,因为模型绑定器是递归函数,因此在模型重建期间它被调用了数百次,并且文化设置操作不是简单的变量设置操作,而是具有不可忽视的成本.最好编写一个全局控制器过滤器来处理文化设置(我总是这样做),因此每个请求只执行一次操作