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

3

我有一个只有一个小数属性的简单模型:

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,我会收到客户端验证错误(即数据验证-数字错误),或者如果我发布1.5,我会收到服务器端模型验证错误-"对于数量来说,值'1.5'无效。"我尝试在Global.asax的Application_Start()中手动设置NumberDecimalSeparator,但没有帮助。
var currentCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
currentCulture.NumberFormat.NumberDecimalSeparator = ".";

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

当我手动向数据库添加一些值并尝试编辑它们时,文本框中显示的值带有点号".",但是当我尝试保存另一个带点号的值时,会出现服务器端验证错误。可能的原因是什么?为什么手动更新区域设置信息没有起作用?
// 编辑: 我的方法是更改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);
}

为什么应用程序启动时它不起作用?

服务器的文化是什么?如果它接受逗号作为小数分隔符,那么您可以修改jquery.validator以接受逗号作为小数分隔符(默认情况下是点)。 - user3559349
@StephenMuecke,服务器的文化是 culture="ru" uiCulture="ru-RU",我也想使用点作为小数分隔符,因为这是默认设置。 - Dmytro
如果将文化更改为“en-US”,它是否有效? - user3559349
@StephenMuecke,是的,它可以。在这种情况下,点号(dot)是客户端和服务器端验证器的有效分隔符。 - Dmytro
尝试将设置文化的代码放在Application_AcquireRequestState中,而不是Application_Start中。 - user3559349
2个回答

3
我认为在Application_Start中设置线程的本地化文化是不起作用的,这是很合理的。您可以在web.config文件中全局设置本地化文化:
<configuration>
    <system.web>
        <globalization uiCulture="en-GB" culture="en-GB" />
    </system.web>
</configuration>

但是,如果你想要(就像你的例子一样)保留俄罗斯文化但使用不同的小数分隔符,那么我认为Application_BeginRequest()可能是一个很好的选择。根据文档所述:

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

但是需要注意,因为这个事件会在每个请求上触发。
我不久前解决了类似的问题。在我的情况下,用户可以在文化之间切换。因此,每个用户文化都保存在数据库中,因此我们使用控制器的Initialize方法而不是Application_BeginRequest()。然后,我们基于当前线程文化设置了所有客户端验证规则。
我认为这样的功能也可以移动到过滤器中,就像这个答案中所示。

非常感谢您! - Alexander

1

关于这个问题,有一篇很好的博客文章。我已经回答了类似的问题

The approach I used is to extend the jQuery validator. It is based on this blogpost. I setted the culture in the metadata to BE-nl. Since this is a pure Dutch website, I don't do any checks further on.

$(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;
}; }); 

I think I used this jQuery library for the globalization


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接