不显眼的日期时间?验证在MVC4 [英] Unobtrusive DateTime? Validation in MVC4

查看:102
本文介绍了不显眼的日期时间?验证在MVC4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我升级的MVC3解决MVC4。迁移后,验证器坏了。

I upgraded an MVC3 solution to MVC4. After the migration, the validator is broken.

我输入的日期,如果我选择德语作为语言,是二零一三年三月二十零日。我得到一个验证错误在MVC4,但不是在MVC3。如果我取代从2013年3月20日的格式20/03/2013​​,它工作在MVC4,但不是在MVC3; - )

My input date, if i select German as language, is "20.03.2013". I get an validation error in MVC4, but not in MVC3. If i replace the format from "20.03.2013" to "20/03/2013" it works in MVC4, but not in MVC3 ;-)

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

I set the UI culture of the current thread to german. The output of the ResX values are in the correct language, so i know there should be no error with the culture., only for the site itself. The error messages are in english, but the site is in german.

我想这意味着验证程序使用了错误的UI文化。

I assume this means the validator uses the wrong UI Culture.

下面是code I使用。

Here is the code i use.


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

我认为有一些错误的默认模型联编,因为呈现的HTML看起来很不错:

I assume there is something wrong with the default model binder, as the rendered html looks good:


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新的MVC应用程序(已安装SP1)的模板我升级的Jscript有关人士透露该船。这并没有影响。

I upgraded the Jscript to the sources that ship when you create a new Mvc application using the Visual Studio 2012 (SP1 is installed) templates. This had no impact.

我有一个CultureModelBinder它读取当前文化走出会议和使用小助手功能设置文化。

I have a CultureModelBinder which reads the current culture out of the Session and sets the culture using a small helper function.


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

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

The culture model binder is the default binder.


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

或许真的在执行顺序改变与产生的问题mvc4?

Maybe something changed in the execution order with mvc4 resulting the problem?

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

Update: The project uses .NET Framework 4.5 as target.

更新2:

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

I have a combo box where the user can select 16 different languages, each might have it's own specific formatting.

例如。
DE-DE - > DD.MM.YYYY;
EN-EN - > DD / MM / YYYY;
EN-US - > MM / DD / YYYY

E.g. DE-de -> DD.MM.YYYY; en-en -> DD/MM/YYYY; en-us -> MM/DD/YYYY

我刚刚得到了有关设置当前区域性提示,这里是证明它应该是正确的,因为它是。当验证失败,这code未击中,它看起来像它发生在客户端。

I just got a hint about setting the current culture, here is the proof it should be correct as it is. This code is not hit when the validators fail, it looks like it happens on the client side.


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

和完整性我的文化模型绑定:

and for completeness my culture model binder:


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

更新:也许有这个问题的相关性:
<一href=\"http://connect.microsoft.com/VisualStudio/feedback/details/705643/a-data-val-date-attribute-is-generated-for-time-fields-in-asp-net-mvc-4\">http://connect.microsoft.com/VisualStudio/feedback/details/705643/a-data-val-date-attribute-is-generated-for-time-fields-in-asp-net-mvc-4

更新:
阅读下面的文章:
<一href=\"http://weblogs.asp.net/scottgu/archive/2010/06/10/jquery-globalization-plugin-from-microsoft.aspx\">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。

added the call. the output was correctly "DE".


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

没有影响到验证...

No affect to the validators...

推荐答案

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

The point is that Mvc3 doesnt validate at all dates on the client side that is the point. You just set the cultrure on the server side....but your culture settings are not reflected at all on the client side...at least the Mvc engine doesnt do it automatically. The only way to handle properly dates and numbers on the client side with cultures that differs from English is to use a a javascript globalization library that is able to parse properly dates in all cultures, and to set the client side culture equal to the server side culture, then you have to redefine properly all validation methods to use globalized functions. Please read this post of my blog that clarifies how to handle properly globalization on the client side: http://www.dotnet-programming.com/post/2011/12/14/Globalization-Validation-and-DateNumber-Formats-in-AspNet-MVC.aspx

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

Moreover, please dont confuse CurrentCulture with CurrentUICulture CurrentUICulture doesnt affect at all the way numbers or dates are handled, but only the resource files containing culture specifi resources such as localized strings.

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

Finally, it is very unefficient to set the culture in the model binder, since the model binder is a recursive function so it si called hundreds of times during model reconstruction, and the culture setting operation is not a simple variable setting operation but it has a not negligible cost. It is better to write a global controller filter to handle culture setting (I always do this way) so the operation is performed just once per request

这篇关于不显眼的日期时间?验证在MVC4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆