在C#ASP .Net MVC中编辑十进制模型属性

时间:2015-03-31 05:59:32

标签: c# asp.net-mvc validation decimal-point

我有一个带有一个十进制属性的简单模型:

public class Model {
    public decimal Quantity { get;set; }
}

在我看来,我有:

@Html.TextBoxFor(m => m.Quantity)
@Html.ValidationMessageFor(m => m.Quantity)

当我尝试使用小数部分(如1.5,2.5等)发布值时,我会在客户端或服务器端获得验证错误,具体取决于我使用的NumberDecimalSeparator。如果我发布1,5,我会收到客户端验证错误(data-val-number为1),或者如果我发布1.5,我会收到服务器端模型验证错误 - "The value '1.5' is not valid for Quantity."。我尝试在Global.asax中的NumberDecimalSeparator上手动设置Application_Start(),但它没有帮助。

var currentCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
currentCulture.NumberFormat.NumberDecimalSeparator = ".";

Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentCulture;

当我手动将一些值添加到数据库并尝试编辑它们时,TextBox中的值以点"."显示,但是当我尝试使用点保存另一个值时,我得到服务器端验证错误。可能是什么原因?为什么手动文化信息更新无效?

//编辑: 我改变currentCulture.NumberFormat.NumberDecimalSeparator的方法有效,但只有在Application_BeginRequest()每次都这样做时才会有效:

protected override void Application_BeginRequest(object sender, System.EventArgs e)
{
       var currentCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
       currentCulture.NumberFormat.NumberDecimalSeparator = ".";
       currentCulture.NumberFormat.NumberGroupSeparator = " ";
       currentCulture.NumberFormat.CurrencyDecimalSeparator = ".";

       Thread.CurrentThread.CurrentCulture = currentCulture;
       Thread.CurrentThread.CurrentUICulture = currentCulture;
       base.Application_BeginRequest(sender, e);
}

为什么它不适用于应用程序启动?

2 个答案:

答案 0 :(得分:3)

我认为它在Application_Start中不起作用是合乎逻辑的,因为你为每个线程设置了文化。

您可以在web.config中全局设置文化:

<configuration>
    <system.web>
        <globalization uiCulture="en-GB" culture="en-GB" />
    </system.web>
</configuration>

但是如果你想(如你的例子中)拥有俄罗斯文化但使用不同的小数分隔符,那么我认为Application_BeginRequest()可能是一个很好的候选人。根据{{​​3}}:

  

作为HTTP管道执行链中的第一个事件发生时   ASP.NET响应请求。

但是你需要小心,因为这个事件在每个请求上被触发。

我不久前解决了类似的问题。在我的情况下,用户可以在不同文化之间切换。因此,每个用户文化都保存在数据库中,因此我们使用Initialize控制器方法而不是Application_BeginRequest()。然后我们根据当前的线程文化设置客户端验证的所有规则。

我认为此类功能也可以像documentation一样移动到过滤器。

答案 1 :(得分:1)

关于这个问题,有一篇很好的博客文章。 I answered this already to a similar question

  

我使用的方法是扩展jQuery验证器。它基于   this blogpost。我将元数据中的文化设置为BE-nl。以来   这是一个纯粹的荷兰网站,我不会进一步检查。

$(function () {
    // Look in metatag what culture we want
    // and set this as culture for the client side.
    var data = $("meta[name='accept-language']").attr("content");
    Globalize.culture(data.toString());

    // Don't validate on keyup event because it will mess up
    // the cursor when replacing values in a textbox.
    $('form').each(function () {
    var validator = $(this).data('validator');
    if (validator) {
        validator.settings.onkeyup = false;
    }
});

// Belgianize/sanitize the numbers inserted
// 1 000 000    =>      1000000
// 1.00         =>      1,00
$.validator.methods.number = function (value, element) {
    var s = value.replace(/\ /g, '').split('.').join(',');

    if (s.split(',').length < 3) {
        var number = Globalize.parseFloat(s);
        if (!isNaN(number)) {
            $(element).val(s);
            return this.optional(element) || true;
        }
    }

    return this.optional(element) || false;
}; }); 
     

我认为我使用this jQuery library进行全球化