我有一个本地化的ASP.NET核心Web应用程序:en-US和it-IT。
在en-US上,小数点分隔符为点,在其中 - 小数点分隔符为逗号。
我有这个ViewModel
public class MyViewModel
{
public int Id {get; set; }
// Omitted
public decimal? Amount{get; set;}
}
对于在 en-US 上呈现创建/编辑页面时的十进制字段,html文本框呈现
1000.00
如果我发布表单,则操作完成且没有错误。
到目前为止一切顺利。
当我在 it-IT 上呈现创建/编辑页面时,html文本框呈现
1000,00(注意逗号)
如果我尝试发布表单,(CLIENT)验证失败与
字段金额必须是数字。
我读到了有关IModelBinder的信息,但我理解的是,当表单在服务器上发布时映射viewModel,在我的情况下,我被客户端验证阻止。
更好的是在en-US时使用dot,而在IT时使用逗号,但只使用点
就可以了答案 0 :(得分:7)
在挖掘深度问题后,我找到了两个解决方案:
来自Stephen Muecke的评论解释了如何将所需的jquery添加到validation for comma and dot的输入
自定义InputTagHelper,将逗号转换为点。这里我只添加了一个十进制类型,但显然你可以添加float和double。
[HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class InvariantDecimalTagHelper : InputTagHelper
{
private const string ForAttributeName = "asp-for";
private IHtmlGenerator _generator;
[HtmlAttributeName("asp-is-invariant")]
public bool IsInvariant { set; get; }
public InvariantDecimalTagHelper(IHtmlGenerator generator) : base(generator)
{
_generator = generator;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);
if (IsInvariant && output.TagName == "input" && For.Model != null && For.Model.GetType() == typeof(decimal))
{
decimal value = (decimal)(For.Model);
var invariantValue = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
output.Attributes.SetAttribute(new TagHelperAttribute("value", invariantValue));
}
}
}
要使用此第二个解决方案,您只需在输入中添加asp-is-invariant,就像这样
<input asp-for="AmountSw" class="form-control" asp-is-invariant="true" />
答案 1 :(得分:0)
转换失败,因为ASP.NET尝试使用当前文化(check this link)转换值。
您需要在请求的当前线程中设置区域性。浏览器将发送当前使用的语言,并使用Request.UserLanguage
发送支持。
您可以使用自定义过滤器,http模块或使用mvc的事件结构自动为每个请求设置文化。 Check this link for a sample
答案 2 :(得分:0)
我尝试了上面提到的自定义验证器,但是它不起作用。我让它像这样工作:
namespace Project.Helpers
{
[HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class InvariantDecimalTagHelper : TagHelper
{
private const string ForAttributeName = "asp-for-invariant";
private readonly IHtmlGenerator _generator;
private readonly InputTagHelper _inputTagHelper;
[HtmlAttributeNotBound]
[ViewContext]
public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; }
[HtmlAttributeName("asp-for-invariant")]
public ModelExpression For { get; set; }
[HtmlAttributeName("asp-format")]
public string Format { get; set; }
[HtmlAttributeName("type")]
public string InputTypeName { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public InvariantDecimalTagHelper(IHtmlGenerator generator)
{
_generator = generator;
_inputTagHelper = new InputTagHelper(_generator);
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
_inputTagHelper.Value = Value;
_inputTagHelper.Name = Name;
_inputTagHelper.InputTypeName = InputTypeName;
_inputTagHelper.Format = Format;
_inputTagHelper.For = For;
_inputTagHelper.ViewContext = ViewContext;
_inputTagHelper.Process(context, output);
if (output.TagName == "input" && _inputTagHelper.For.Model != null && _inputTagHelper.For.Model.GetType() == typeof(decimal))
{
decimal value = (decimal)(_inputTagHelper.For.Model);
var invariantValue = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
output.Attributes.SetAttribute(new TagHelperAttribute("value", invariantValue));
}
}
}
}
在ViewImports中:
@addTagHelper *, Project
在视图中:
<input asp-for-invariant="numberProp"/>