什么是处理与不同的文化验证的最佳方法 [英] What is the best way to handle validation with different culture

查看:147
本文介绍了什么是处理与不同的文化验证的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个多语种的MVC应用程序。我在我的申请表格,我有字段中输入成本。我能够使用西班牙文化创造的纪录。

I am trying to build a multilingual MVC application. I have a form in my application and I have field to enter a cost. I am able to create a record using the spanish culture.

但在试图更新我越来越jQuery验证虚假备案。而我得到一个默认的错误消息为:

But on trying to update the record I am getting jquery validation false. and I am getting a default error message as:

字段必须是数字。

在我的视图模型我已经设置了以下属性。

In my view model I have set the following attributes.

[LocalizedDisplayName("Label_Cost")]
[RegularExpression("^[^<>,<|>]+$", ErrorMessage = null, ErrorMessageResourceName = "Error_Message_Html_Tags_Prevented", ErrorMessageResourceType = typeof(Resources))]
[Range(0, 9999.99, ErrorMessage = null, ErrorMessageResourceName = "Error_Message_Cost_Not_Valid", ErrorMessageResourceType = typeof(Resources))]
public decimal? Cost { get; set; }

我在Gobal.asax文件中设置与下列

I have set in my Gobal.asax file with following

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    try
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("CurrentCulture");
        string culutureCode = cookie != null && !string.IsNullOrEmpty(cookie.Value) ? cookie.Value : "en";
        CultureInfo ci = new CultureInfo(culutureCode);
        System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
        System.Threading.Thread.CurrentThread.CurrentCulture =
        CultureInfo.CreateSpecificCulture(ci.Name);
    }
    catch(Exception ex)
    {
        // Code
    }
}

和上面的方法的工作方式在改变文化在服务器端的预期。但在非英语文化中的客户端验证休息,如JavaScript只承认十进制文本。我想知道延长与文化的具体验证了MVC客户端验证的最佳方式。

and the above method works as expected at server side in changing the culture . But the client side validation breaks on non-english cultures as javascript recognizes only decimal literals. I'd like to know the best way to extend the mvc client side validation with culture specific validation.

修改

参考Mike的网址我已经做以下JS中捆绑的变化。 JS捆绑如下:

With reference to Mike's url I have made following changes in Js bundle. Js bundle is as follows

public static void RegisterBundles(BundleCollection bundles)
{
   BundleTable.EnableOptimizations = true;

  bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/globalisation").Include(
               "~/Scripts/globalize.js",
               "~/Scripts/globalize/currency.js",
                "~/Scripts/globalize/date.js",
                "~/Scripts/globalize/message.js",
                "~/Scripts/globalize/number.js",
                "~/Scripts/globalize/plural.js",
                "~/Scripts/globalize/relative-time.js"));

  bundles.Add(new ScriptBundle("~/bundles/globalisationEN").Include(
               "~/Scripts/GlobalisationCulture/globalize.culture.en-AU.js"));

            bundles.Add(new ScriptBundle("~/bundles/globalisationES").Include(
               "~/Scripts/GlobalisationCulture/globalize.culture.es-AR.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryuiEN").Include(
                        "~/Scripts/jquery-ui-1.10.3.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryuiES").Include(
                        "~/Scripts/jquery-ui-1.10.3.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                "~/Scripts/jquery.validate.js",
                "~/Scripts/jquery.validate.unobtrusive.js",
                "~/Scripts/jquery.unobtrusive-ajax.js",
                "~/Scripts/jquery.validate.globalize.js"));
}

在页面布局我已经实现如下:

In the layout page I have implemented as follows

HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("CurrentCulture");
        string culutureCode = cookie != null && !string.IsNullOrEmpty(cookie.Value) ? cookie.Value : "en";
        if (culutureCode.Equals("en-AU", StringComparison.OrdinalIgnoreCase))
        {
            culutureCode = "EN";
        }
        else if (culutureCode.Equals("es-AR", StringComparison.OrdinalIgnoreCase))
        {
            culutureCode = "ES";
        }
        else
        {
            culutureCode = "EN";
        }
@Scripts.Render("~/bundles/jquery",
                    "~/bundles/globalisation",
                    string.Format("~/bundles/globalisation{0}", culutureCode),
                    "~/bundles/jqueryval",
                    string.Format("~/bundles/jqueryui{0}", culutureCode))

推荐答案

有2的jQuery插件全球化。

解决方案

旧的版本是 v0.0.1 包含一个脚本全球化.js文件,它有一个子文件夹文化在这里你可以找到所有的脚本,文化,例如:

There are 2 jQuery Globalize plugins.


  • globalize.culture.en-AU.js

  • globalize.culture.es-AR.js

这些脚本允许你为你想要所以这将是完美的罚款有你的包建这种方式添加尽可能多的文化:

  • globalize.culture.en-AU.js
  • globalize.culture.es-AR.js
those scripts allow you to add as many cultures as you want so it would be perfectly fine to have your bundle built this way:

全球化时代将有本地化脚本的集合,你可以设置只需使用:

bundles.Add(new ScriptBundle("~/bundles/globalisation").Include( "~/Scripts/globalize.js", "~/Scripts/cultures/globalize.culture.en-AU.js", "~/Scripts/cultures/globalize.culture.es-AR.js" ));

Globalize will have a collection of localization scripts which you can set simply using:

or

它可以使用某种接近找出哪些是你想用最接近的文化。
如果您在包已加载 globalize.culture.es-AR.js 你可以设置 Globalize.culture('上课'); 全球化时代将能够弄清楚,你要使用的ES-AR'文化;当然,如果你已经添加了 globalize.culture.es.js 装载机会选择这最后一个。

Globalize.culture('es-AR');

全球化时代的jQuery(稳定)的新版本是 V1.0.0 和它的作品在一个完全不同的方式。

It can use some sort of proximity to figure out which is the closest culture you want to use. If you have loaded in your bundle globalize.culture.es-AR.js you can set Globalize.culture('es'); and Globalize would be able to figure out that you want to use the 'es-AR' culture; of course if you have added globalize.culture.es.js the loader would chose this last one.

它仍然有一个名为 globalize.js 主要的脚本文件,但你必须添加更多的脚本,使其工作。

The new version of jQuery Globalize (stable) is v1.0.0 and it works in a completely different way.

有人建立了一个工具它告诉你,你需要根据什么脚本是什么模块(数字,日期,货币)类型要使用。

It still have the main script file called globalize.js but you have to add a lot more scripts to make it work.

如果你选择使用V1.0.0,你会看到该工具会建议包括基本的脚本(仅限数字):

Someone has built a tool which tell you exactly what script you need depending on what type of module (number, dates, currencies) you want to use.


  • cldr.js

  • CLDR / event.js

  • CLDR / supplemental.js

  • globalize.js

  • 全球化时代/ number.js

再加上一些CLDR JSON脚本:

  • cldr.js
  • cldr/event.js
  • cldr/supplemental.js
  • globalize.js
  • globalize/number.js

  • CLDR /补充/ likelySubtags.json

  • CLDR /主/ {}区域/numbers.json

  • CLDR /补充/ numberingSystems.json

您可以在核心包和的数字包结果。
如果您想验证日期,这是
更多信息这里

  • cldr/supplemental/likelySubtags.json
  • cldr/main/{locale}/numbers.json
  • cldr/supplemental/numberingSystems.json

这些都是JSON文件,你不能捆绑他们。您可以在运行时加载它们做这样的事情:

You can find these files in the core package and the numbers package.
If you want to validate dates this is the package. More info here.

These are all json file and you cannot bundle them. You can loaded them in run-time doing something like this:

不管怎样;比方说,你要坚持到老v0.0.1仍然是最好的。结果
你的包将在全球化脚本和文化的:

Application.loadCulture = function (culture) { $.when( $.get(Application.CldrFetch + '/' + culture + '/' + encodeURIComponent("likelySubtags.json")), $.get(Application.CldrFetch + '/' + culture + '/' + "numberingSystems.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "plurals.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "ordinals.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "currencyData.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "timeData.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "weekData.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "ca-gregorian.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "timeZoneNames.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "numbers.json"), $.get(Application.CldrFetch + '/' + culture + '/' + "currencies.json") ) .then(function () { // Normalize $.get results, we only need the JSON, not the request statuses. return [].slice.apply(arguments, [0]).map(function (result) { return result[0]; }); }).then(Globalize.load).then(function () { Globalize.locale(culture); }); };

Anyway; let's say you want to stick to the old v0.0.1 which is still the best.
Your bundle will have the globalize script and the culture ones:

jQuery验证提供,你可能要考虑一些其他的附加扩展:

bundles.Add(new ScriptBundle("~/bundles/globalisation").Include( "~/Scripts/globalize.js", "~/Scripts/cultures/globalize.culture.en-AU.js", "~/Scripts/cultures/globalize.culture.es-AR.js" ));


  • 附加-methods.js

  • 本地化/ messages_es_AR.js(对于文化错误消息)

我已经看到了你设置了 Application_AcquireRequestState 你的文化。有人认为这是更好地做到这一点在的Application_BeginRequest ,因为它是在前面的管道处理:

  • additional-methods.js
  • localization/messages_es_AR.js (error messages for the culture)
I have seen that you're setting your culture in the Application_AcquireRequestState. Someone suggest it's better to do it in Application_BeginRequest as it is processed earlier in the pipe:

看来,您使用的是验证这一 jQuery插件。我通常做的,只要我打开我配置的文化脚本,并设置自定义的验证是:

protected void Application_BeginRequest(object sender, EventArgs e) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("CurrentCulture"); string cultureCode = cookie != null && !string.IsNullOrEmpty(cookie.Value) ? cookie.Value : "en"; CultureInfo ci = new CultureInfo(cultureCode); System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureCode); System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture; }

It seems that you're using this jQuery plugin for the validation. What I normally do is as soon as I load the script I configure the culture and set the custom validation:

你缺少一件事是小数的典范粘结剂:

Globalize.culture(this.culture); $.validator.methods.number = function (value, element) { return this.optional(element) || jQuery.isNumeric(Globalize.parseFloat(value)); }; $.validator.methods.date = function (value, element) { return (this.optional(element) || Globalize.parseDate(value)); }; jQuery.extend(jQuery.validator.methods, { range: function (value, element, param) { var val = Globalize.parseFloat(value); return this.optional(element) || (val >= param[0] && val <= param[1]); } });

One thing that you're missing is a model binder for decimals:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

这是你需要pretty太多的一切。

This is pretty much everything you need.

有只有一个恼人的问题,这种方法。结果
比方说,你正在使用的文化 EN-AU ,你输入你的数字字段的值:10,4。
这个数字是在 ES-AR 完全有效的,但它应该是不合法的 EN-AU 文化。

There's only an annoying problem with this approach.
Let's say you're using the culture en-AU and you input in your numeric field a value: 10,4. This number is perfectly valid in es-AR but it should be non-valid for the en-AU culture.

全球化时代的jQuery会考虑有效的,也因为这将是traslate 104这里:

jQuery Globalize will consider it valid anyway as it would traslate it to 104 here:

$.validator.methods.number = function (value, element) {
    return this.optional(element) || jQuery.isNumeric(Globalize.parseFloat(value));
};

Globalize.parseFloat('10,4')的文化EN-AU将改变这个数字104。

Globalize.parseFloat('10,4') for the culture en-AU would transform that number to 104.

如果您 Globalize.parseFloat做同样的同样的事情会发生('10 2.4)的文化ES-AR;它会成为再次,104。

Same thing would happen if you do the same for Globalize.parseFloat('10.4') for the culture es-AR; it would become, again, 104.

您可以检查这种行为在运行此小提琴

You can check this behaviour running this fiddle.

两者,因为它们将被用作小数点分隔符和千位分隔符有效的符号。

Both , and . are valid symbols as they would be used as decimal separator and thousands separator.

有关于这个话题开的几个问题 github上,我想这将是困难的,因为修复他们现在工作的新版本,其中相同的问题仍然存在,顺便说一句。

There are a few issues open on this topic on github and I guess it would be hard to fix since they are now working on the new version, where the same problem persists, by the way.

您要去面对服务器端与我们的<一个同样的问题href=\"https://github.com/Leftyx/Globalize001Validation/blob/master/Globalize001Validation/Infrastructure/DecimalModelBinder.cs#L22\">decimal模型绑定:

You're going to face the same problem on the server-side with our decimal model binder:

decimal.Parse('10,4', NumberStyles.Any, CultureInfo.CurrentCulture);

其中CultureInfo.CurrentCulture是EN-AU'将再次产生同样的结果: 104

这能在那里放置一个断点,看看它是如何转换的价值。

It can place a breakpoint there and see how it converts the value.

我想这可能会更容易解决,可能使用一些常规的前pressions。

I guess probably this would be easier to fix, maybe using some regular expressions.

如果你想与我创建了两个库的这里这里

If you want to play with the solution with jQuery Validator v.0.1.1 or jQuery Validator v.1.0.0 I've created two repositories here and here.

这篇关于什么是处理与不同的文化验证的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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