C# 用不同的文化处理验证的最佳方式是什么
我正在尝试构建一个多语言的MVC应用程序。我在申请表中有一个表格,我有一个字段来输入成本。我能够使用西班牙文化创建一个记录 但是在尝试更新记录时,我发现jquery验证是错误的。我收到一条默认错误消息,如下所示: 该字段必须是数字 在我的视图模型中,我设置了以下属性C# 用不同的文化处理验证的最佳方式是什么,c#,asp.net-mvc,validation,asp.net-mvc-4,globalization,C#,Asp.net Mvc,Validation,Asp.net Mvc 4,Globalization,我正在尝试构建一个多语言的MVC应用程序。我在申请表中有一个表格,我有一个字段来输入成本。我能够使用西班牙文化创建一个记录 但是在尝试更新记录时,我发现jquery验证是错误的。我收到一条默认错误消息,如下所示: 该字段必须是数字 在我的视图模型中,我设置了以下属性 [LocalizedDisplayName("Label_Cost")] [RegularExpression("^[^<>,<|>]+$", ErrorMessage = null, ErrorMessag
[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; }
在服务器端,上述方法在更改区域性方面的效果与预期一样。但是客户端验证在非英语文化中中断,因为javascript只识别十进制文本。我想知道用特定于区域性的验证扩展mvc客户端验证的最佳方法
编辑
关于Mike的url,我在Js包中做了以下更改。Js包如下所示
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"));
}
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))
在布局页面中,我实现了如下
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"));
}
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))
您已在RegisterBundles中添加了捆绑包,但未在布局页面中使用它们。您还在RegisterBundles中添加了冗余的jqueryui文件更新您的RegisterBundles方法,如下所示:
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/jqueryui").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"));
}
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);
});
};
然后更新布局页面,如下所示:
@section Scripts
{
@Scripts.Render("~/bundles/jquery",
"~/bundles/globalisation",
"~/bundles/globalisationEN",
"~/bundles/globalisationES",
"~/bundles/jqueryval",
"~/bundles/jqueryui"))
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
return this.optional(element) ||
!isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('es-AR'); //set spanish culture
});
</script>
}
@节脚本
{
@Scripts.Render(“~/bundles/jquery”,
“~/bundles/全球化”,
“~/bundles/globalizationen”,
“~/bundles/全球化”,
“~/bundles/jqueryval”,
“~/bundles/jqueryui”))
$.validator.methods.number=函数(值,元素){
返回此值。可选(元素)||
!isNaN(Globalize.parseFloat(value));
}
$(文档).ready(函数(){
Globalize.culture('es-AR');//设置西班牙文化
});
}
希望这会有所帮助:)有两个jQuery全球化插件 旧版本包含一个脚本
globalize.js
,它有一个子文件夹cultures
,您可以在其中找到所有脚本区域性,例如:
- globalize.culture.en-AU.js
- globalize.culture.es-AR.js
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
将有一组本地化脚本,您可以使用以下方法设置这些脚本:
Globalize.culture('en-AU');
或
它可以使用某种接近度来确定您想要使用的最接近的文化。
如果您已在bundle中加载了globalize.culture.es-AR.js
,则可以设置globalize.culture('es')
和Globalize
将能够确定您想要使用“es AR”文化;当然,如果您添加了globalize.culture.es.js
,加载程序会选择最后一个
jqueryglobalize(stable)的新版本是,它以一种完全不同的方式工作
它仍然有一个名为globalize.js
的主脚本文件,但您必须添加更多的脚本才能使其正常工作
有人构建了一个脚本,它会根据您想要使用的模块类型(编号、日期、货币)准确地告诉您需要什么脚本
如果您选择使用v1.0.0,您将看到该工具将建议包括基本脚本(仅限数字):
- cldr.js
- cldr/event.js
- cldr/supplemental.js
- globalize.js
- globalize/number.js
- cldr/supplemental/likelySubtags.json
- cldr/main/{locale}/numbers.json
- cldr/supplemental/numberingSystems.json
如果要验证日期,请使用此选项。 更多信息 这些都是json文件,您无法绑定它们。您可以在运行时执行以下操作加载它们:
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/jqueryui").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"));
}
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);
});
};
无论如何;比方说,您希望坚持旧的v0.0.1,它仍然是最好的。您的捆绑包将包含全球化脚本和文化脚本:
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(区域性的错误消息)
应用程序\u AcquisiteRequestState
中设置区域性。有人建议最好在应用程序_BeginRequest
中执行此操作,因为它是在管道中较早处理的:
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;
}
看来你是在用这个来验证。我通常会做的是,在加载脚本后,配置区域性并设置自定义验证:
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]);
}
});
可以在Global.asax应用程序\u Start
中设置:
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
这几乎是你所需要的一切
这种方法只有一个恼人的问题。假设您正在使用区域性
en AU
,并在数字字段中输入一个值:10,4。
此数字在es AR
中完全有效,但在en AU
区域性中应无效
jQuery全球化将考虑它是有效的,因为它会把它拖到104以下:
$.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')做同样的事情,那么文化就是这样;它将再次变成104
运行此命令可以检查此行为
、
和
都是有效的符号,因为它们将用作十进制分隔符和千位分隔符
在这个主题上还有一些问题有待解决,我想这将很难解决,因为他们现在正在开发新版本,顺便说一句,同样的问题仍然存在
您将在服务器端面临与我们相同的问题:
CultureInfo.CurrentCulture为“en-AU”时,同样会产生相同的结果:104
它可以在那里放置断点,并查看如何转换值