2013-01-18 66 views
21

Ràng buộc mô hình trong ASP.NET MVC là rất tốt, nhưng nó sau cài đặt miền địa phương. Trong dấu phân cách thập phân của dấu phẩy của tôi là dấu phẩy (','), nhưng người dùng cũng sử dụng dấu chấm ('.'), Vì chúng lười chuyển đổi bố trí. Tôi muốn điều này được triển khai ở một nơi cho tất cả các trường decimal trong các mô hình của tôi.Chấp nhận dấu phẩy và dấu chấm làm dấu phân cách thập phân

Tôi có nên triển khai Nhà cung cấp giá trị của riêng mình (hoặc Mô hình sự kiện Binder) cho loại decimal hoặc tôi đã bỏ lỡ một số cách đơn giản để thực hiện việc này?

+0

Các giải pháp chấp nhận không hoạt động trong một số trường hợp. Liên kết sau có giải pháp hoạt động cho tất cả các trường hợp: https://stackoverflow.com/a/5117441/1314276 –

Trả lời

35

cách sạch nhất là thực hiện mô hình chất kết dính của riêng bạn

public class DecimalModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

     return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue); 
     // of course replace with your custom conversion logic 
    }  
} 

Và đăng ký nó bên trong Application_Start():

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()); 
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder()); 

Điểm Uy Tín: Default ASP.NET MVC 3 model binder doesn't bind decimal properties

+1

Nơi đặt lớp DecimalModelBinder? –

+1

@ ИванБишевац Tôi đặt mỏ tại \ Common \ ModelBinders. –

+0

Convert.ToDecimal (valueProviderResult.AttemptedValue) hoạt động tốt cho dấu phẩy, nhưng đối với dấu chấm số nhân với 100. Gợi ý? –

1
var nfInfo = new System.Globalization.CultureInfo(lang, false) 
{ 
    NumberFormat = 
    { 
     NumberDecimalSeparator = "." 
    } 
}; 
Thread.CurrentThread.CurrentCulture = nfInfo; 
Thread.CurrentThread.CurrentUICulture = nfInfo; 
+0

plus. tôi yêu anh bạn! –

5

Để xử lý đúng đắn tách nhóm , chỉ cần thay thế

Convert.ToDecimal(valueProviderResult.AttemptedValue); 

trong câu trả lời được lựa chọn với

Decimal.Parse(valueProviderResult.AttemptedValue, NumberStyles.Currency); 
+2

Hoặc NumberStyles.Any nếu bạn muốn đi buck hoang dã. – user15741

2

Nhờ câu trả lời được chấp nhận tôi đã kết thúc với việc thực hiện sau đây để xử lý float, double và số thập phân.

public abstract class FloatingPointModelBinderBase<T> : DefaultModelBinder 
{ 
    protected abstract Func<string, IFormatProvider, T> ConvertFunc { get; } 

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (valueProviderResult == null) return base.BindModel(controllerContext, bindingContext); 
     try 
     { 
      return ConvertFunc.Invoke(valueProviderResult.AttemptedValue, CultureInfo.CurrentUICulture); 
     } 
     catch (FormatException) 
     { 
      // If format error then fallback to InvariantCulture instead of current UI culture 
      return ConvertFunc.Invoke(valueProviderResult.AttemptedValue, CultureInfo.InvariantCulture); 
     } 
    } 
} 

public class DecimalModelBinder : FloatingPointModelBinderBase<decimal> 
{ 
    protected override Func<string, IFormatProvider, decimal> ConvertFunc => Convert.ToDecimal; 
} 

public class DoubleModelBinder : FloatingPointModelBinderBase<double> 
{ 
    protected override Func<string, IFormatProvider, double> ConvertFunc => Convert.ToDouble; 
} 

public class SingleModelBinder : FloatingPointModelBinderBase<float> 
{ 
    protected override Func<string, IFormatProvider, float> ConvertFunc => Convert.ToSingle; 
} 

Sau đó, bạn chỉ cần thiết lập ModelBinders của bạn trên Application_Start phương pháp

ModelBinders.Binders[typeof(float)] = new SingleModelBinder(); 
ModelBinders.Binders[typeof(double)] = new DoubleModelBinder(); 
ModelBinders.Binders[typeof(decimal)] = new DecimalModelBinder(); 
Các vấn đề liên quan