不显眼的DateTime? 验证在MVC4(Unobtrusive DateTime? Vali

2019-08-03 07:53发布

我升级的MVC3解决MVC4。 迁移后,验证被打破。

我输入的日期,如果我选择德语作为语言,是“2013年3月20日”。 我得到一个验证错误在MVC4,但不是在MVC3。 如果我从“2013年3月20日”替代格式“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读取当前文化走出会议并设置使用小助手功能的文化。

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

文化模型绑定是默认的粘合剂。

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

或许真的与mvc4导致问题的执行顺序改变了吗?

更新:该项目采用.NET框架4.5的目标。

更新2:

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

例如DE-DE - > DD.MM.YYYY; 烯烯 - > 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);

没有影响到验证...

Answer 1:

问题的关键是,MVC3犯规在客户端上的是点的所有日期验证。 您只需设置在服务器端的cultrure ....但你的文化设置不会反映在客户端在所有...至少MVC的发动机犯规自动执行。 要妥善处理的唯一方法日期,并与来自英国不同文化的客户端编号是使用AA的JavaScript全球化库,能够正确地解析在所有文化中的日期,并设置客户端文化等同于服务器端的文化,那么你必须正确地重新定义所有的验证方法使用全球化功能。 请阅读这篇文章我的博客来阐明如何处理在客户端正确全球化: http://www.dotnet-programming.com/post/2011/12/14/Globalization-Validation-and-DateNumber-Formats-in -AspNet-MVC.aspx

此外,请不要混淆的CurrentUICulture的CurrentUICulture的CurrentCulture犯规在一路数字影响或日期的处理,但只包含文化specifi资源的资源文件,如本地化的字符串。

最后,这是非常效率不高,设置文化模型绑定,因为该模型粘合剂是递归函数,因此对所谓的模型重建过程中数百次,和文化背景的操作不是一个简单的变量设置操作,但它有一个不可忽略的成本。 这是更好地写全局控制器过滤器来处理文化背景(我总是这样),所以每个请求只执行一次操作



Answer 2:

尝试覆盖默认日期验证:

// Replace dots so jq validator can understand what's going on
$(function () {
    $.validator.addMethod(
    "date",
    function (value, element) {
        var s = value;
        s = value.replace(/\./g, '/');

        // Chrome requires tolocaledatestring conversion, otherwise just use the slashed format
        var d = new Date();
        return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value))) || !/Invalid|NaN/.test(new Date(s));
    },
    ""
    );
});

$.validator.unobtrusive.parse();


Answer 3:

翻翻与ILSpy代码这似乎是新引进的ClientDataTypeModelValidatorProvider,它是将数据-VAL-date属性。

如果你想恢复到MVC3风格功能,那么只需从模型验证供应商的名单中撤出,供应商做的伎俩。

它并没有解决这个问题,但在几行代码就可以消除由jQuery验证缺乏全球化的问题。

using System.Web.Mvc;

...

protected void Application_Start()
{
  var providers = ModelValidatorProviders.Providers;
  var clientDataTypeModelValidatorProvider = providers.OfType<ClientDataTypeModelValidatorProvider>().FirstOrDefault();
  if ( clientDataTypeModelValidatorProvider != null )
  {
    providers.Remove( clientDataTypeModelValidatorProvider );
  }

  ...
}


Answer 4:

Microsoft建议从mvc4从MVC3项目模板老jquery.validate.js更换新jquery.validate.js。 此作品,但可笑的是,该错误是不是在MVC4,它是在MVC3。

我们使用的是由Francesco描述的方式,请参阅接受的答案。



Answer 5:

如果这只发生在Chrome则是由于其在日期的确认文化错误jQuery的版本。



文章来源: Unobtrusive DateTime? Validation in MVC4