【问题标题】:ASP.NET Core localization decimal field dot and commaASP.NET Core 本地化十进制字段点和逗号
【发布时间】:2017-08-25 12:09:14
【问题描述】:

我有一个本地化的 ASP.NET Core Web 应用程序:en-US 和 it-IT。

在 en-US 中,小数点分隔符是点,在 it-IT 中,小数点分隔符是逗号。

我有这个 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(注意逗号)

如果我尝试发布表单,(客户)验证 fail 使用

字段金额必须是数字。

我阅读了有关 IModelBinder 的信息,但我了解当表单发布在服务器上时映射 viewModel,在我的情况下,我被客户端验证阻止。

en-US 时最好使用点,it-IT 时使用逗号,但只使用点也可以

【问题讨论】:

  • 需要编写脚本来修改jquery验证器
  • 你能给我一些关于这个的其他信息吗?
  • 我看看能不能很快找到你的链接
  • 例如参考this article(但您需要根据文化有条件地添加它)
  • @Ravikumar,这是服务器端,不是客户端验证

标签: c# asp.net asp.net-mvc asp.net-core


【解决方案1】:

深入挖掘问题后,我找到了两个解决方案:

Stephen Muecke 的评论解释了如何将所需的 jquery 添加到 validation for comma and dot 的输入中

自定义 InputTagHelper 将逗号转换为点。这里我只添加了一个十进制类型,但显然你可以添加浮点和双精度。

[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" />

【讨论】:

  • 它们都不适合我。当我输入 123,00 ,发布表格并再次打开它时,我得到 12300.00 那里。这是第一种情况。第二种情况根本不起作用
【解决方案2】:

转换失败,因为 ASP.NET 尝试将值转换为其当前区域性 (check this link)。 您需要在请求的当前线程中设置文化。浏览器将通过Request.UserLanguage 发送它当前使用和支持的语言。

您可以实现自定义过滤器、http 模块或使用 mvc 的事件结构为每个请求自动设置区域性。 Check this link for a sample.

【讨论】:

  • OP 询问的是 客户端 端验证,而不是服务器端
  • 是的,但即使十进制输入通过 it-IT 文化客户端验证,服务器在解析错误文化中发布的字符串时也会返回错误。
  • 如果他们设置了服务器端文化则不会。再次阅读问题-关于客户端验证
【解决方案3】:

我尝试了上面提到的自定义验证器,但它不起作用。我让它像这样工作:

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"/>

【讨论】:

  • 什么是 numberProp ?
猜你喜欢
  • 2011-12-27
  • 2015-09-20
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多