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

Posted

技术标签:

【中文标题】在 C# ASP .Net MVC 中编辑十进制模型属性【英文标题】:Edit decimal model properties in C# ASP .Net MVC 【发布时间】:2015-03-31 05:59:32 【问题描述】:

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

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 我得到服务器端模型验证错误 - "The value '1.5' is not valid for Quantity."。我尝试在 Global.asax 中的 Application_Start() 上手动设置 NumberDecimalSeparator,但没有帮助。

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);

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

【问题讨论】:

服务器的文化是什么?如果它接受小数点分隔符作为逗号,那么您可以修改 jquery.validator 以接受小数点分隔符作为逗号(默认情况下它是一个点) @StephenMuecke,服务器的文化是culture="ru" uiCulture="ru-RU" 我也想使用点作为小数点分隔符,默认情况下。 如果你改变文化(比如en-US)会起作用吗? @StephenMuecke,是的,确实如此。在这种情况下,点是客户端和服务器端验证器的有效分隔符。 尝试将用于设置文化的代码放在 Application_AcquireRequestState 而不是 Application_Start 【参考方案1】:

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

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

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

但是,如果您希望(如您的示例)具有俄罗斯文化但使用不同的小数分隔符,那么我认为 Application_BeginRequest() 可能是一个不错的选择。根据documentation:

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

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

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

我认为这样的功能也可以像this answer一样移动到过滤器中。

【讨论】:

非常感谢!【参考方案2】:

有一篇关于这个问题的优秀博文。 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 来进行全球化

【讨论】:

以上是关于在 C# ASP .Net MVC 中编辑十进制模型属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 ASP.Net MVC 2 脚手架创建编辑表单

asp.net mvc学习

ASP.net 验证码(C#) MVC

如何在 ASP.Net MVC 6 中编辑和继续

如何在 C# 和 ASP.NET MVC 中读取/写入 cookie

在 asp.net core 5 MVC 视图中从 C# 代码调用 JavaScript 函数