在数据库十进制类型中保存逗号分隔数

时间:2015-01-23 17:04:50

标签: asp.net-mvc database csv cultureinfo

我们有大型MVC(5.0)应用程序,我们在数据库中保存了大量的十进制数据。 UI中有货币和小数输入。现在,一个新的变更请求显示了UI和表单中逗号分隔数字的所有数值。我们有一个jQuery函数,可以将这些值更改为正确的格式。

我们的类字段被定义为十进制以接受这些值。当我尝试用逗号保存数据时出现问题。我们使用jQuery.ajax来POST表单,这些表单正在加密逗号分隔的数字。

我不想去使用cultureInfo修改每个表单。有没有更好的方法,我设置一次,当我尝试保存在db中时,它会接受并转换这些以逗号分隔的数字?

我尝试在Global.asax中设置文化信息,如:

protected void Application_BeginRequest()
{
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
}

这似乎不起作用。有没有好的和干净的方法来修复这个问题而不改变每个字段?

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,我通过写下ModelBinder来解决我的问题

public class MyModelBinder : DefaultModelBinder
{
     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(decimal) || bindingContext.ModelType == typeof(Nullable<decimal>))
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueProviderResult != null)
            {
                decimal result;
                var array = valueProviderResult.RawValue as Array;
                string value;
                if (array != null && array.Length > 0)
                {
                    value = array.GetValue(0).ToString().Replace(",", ""); ;
                    if (decimal.TryParse(value.ToString(), out result))
                    {
                        string val = result.ToString(CultureInfo.InvariantCulture.NumberFormat);
                        array.SetValue(val, 0);
                    }
                }
            }
        }
        else if (bindingContext.ModelType == typeof(int) || bindingContext.ModelType == typeof(Nullable<int>))
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueProviderResult != null)
            {
                int result;
                var array = valueProviderResult.RawValue as Array;
                string value;
                if (array != null && array.Length > 0)
                {
                    value = array.GetValue(0).ToString().Replace(",", ""); 
                    if (int.TryParse(value.ToString(), out result))
                    {
                        string val = result.ToString(CultureInfo.InvariantCulture.NumberFormat);
                        array.SetValue(val, 0);
                    }
                }
            }
        }
        else if (bindingContext.ModelType == typeof(long) || bindingContext.ModelType == typeof(Nullable<long>))
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueProviderResult != null)
            {
                long result;
                var array = valueProviderResult.RawValue as Array;
                string value;
                if (array != null && array.Length > 0)
                {
                    value = array.GetValue(0).ToString().Replace(",","");
                    if (long.TryParse(value, out result))
                    {
                        string val = result.ToString(CultureInfo.InvariantCulture.NumberFormat);
                        array.SetValue(val, 0);
                    }
                }
            }
        }
        var res = base.BindModel(controllerContext, bindingContext);
        return res;
    }
}

并将这些代码添加到Application_Start

中的global.asax
        ModelBinders.Binders.DefaultBinder = new MyModelBinder();

答案 1 :(得分:0)

最后,我找到了一个包含3个步骤的解决方案:

  1. 添加类以覆盖DefaultModelBinder

    public class DecimalModelBinder : DefaultModelBinder
    {
       public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
       {
        var valueProvider = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    
        object result = null;
        try
        {
            if (!string.IsNullOrEmpty(valueProvider.AttemptedValue))
                result = decimal.Parse(valueProvider.AttemptedValue);
        }
        catch (FormatException e)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, e);
        }
    
        return result;
    }
    

    }

  2. 在Application_Start

    中的Global.asax中调用此类
    ModelBinders.Binders.Add(typeof(decimal), new GOA.Department.ANS.Web.Model.DecimalModelBinder());
    ModelBinders.Binders.Add(typeof(decimal?), new GOA.Department.ANS.Web.Model.DecimalModelBinder());
    
  3. 上面的代码将解决服务器端验证问题。我们仍然需要使用jquery.validate在客户端进行验证。答案是扩展验证方法。

    1. 调用jquery.validate.js后,在页面中添加这些行或创建一个单独的.js文件,最后将调用该文件:

      $.validator.methods.range = function (value, element, param) {
        var val = value.replace(",", "");
        return this.optional(element) || (val >= param[0] && val <= param[1]);
      }
      
      $.validator.methods.min = function (value, element, param) {
        var val = value.replace(",", "");
        return this.optional(element) || (val >= param);
      }
      
      $.validator.methods.max = function (value, element, param) {
        var val = value.replace(",", "");
        return this.optional(element) || (val <= param);
      }
      
      $.validator.methods.number = function (value, element) {
        return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
      }