以数据库十进制类型保存逗号分隔的数字
save comma separated number in databse decimal type
我们有大型 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;
}
这似乎不起作用。有什么好的、干净的方法可以在不更改每个字段的情况下解决这个问题吗?
我遇到了同样的问题,我通过如下写 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;
}
}
并将这些代码添加到 global.asax
中的 Application_Start
ModelBinders.Binders.DefaultBinder = new MyModelBinder();
最后我找到了一个包含 3 个步骤的解决方案:
添加class覆盖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;
}
}
在Global.asaxApplication_Start
中调用这个class
ModelBinders.Binders.Add(typeof(decimal), new GOA.Department.ANS.Web.Model.DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new GOA.Department.ANS.Web.Model.DecimalModelBinder());
以上代码将解决服务器端验证。我们仍然需要使用 jquery.validate 在客户端进行验证。答案是扩展验证方法。
调用 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);
}
我们有大型 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;
}
这似乎不起作用。有什么好的、干净的方法可以在不更改每个字段的情况下解决这个问题吗?
我遇到了同样的问题,我通过如下写 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;
}
}
并将这些代码添加到 global.asax
Application_Start
ModelBinders.Binders.DefaultBinder = new MyModelBinder();
最后我找到了一个包含 3 个步骤的解决方案:
添加class覆盖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; }
}
在Global.asaxApplication_Start
中调用这个classModelBinders.Binders.Add(typeof(decimal), new GOA.Department.ANS.Web.Model.DecimalModelBinder()); ModelBinders.Binders.Add(typeof(decimal?), new GOA.Department.ANS.Web.Model.DecimalModelBinder());
以上代码将解决服务器端验证。我们仍然需要使用 jquery.validate 在客户端进行验证。答案是扩展验证方法。
调用 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); }