2009-11-22 57 views
5

有沒有什麼辦法可以讓UpdateModel或TryUpdateModel將貨幣或貨幣格式化的值(如$ 1,200.00)解析爲小數點而不會發出大塊?帶貨幣格式化值的TryUpdateModel?

+0

我難倒了堆棧?它似乎不應該那麼辛苦? – 2009-11-23 15:49:32

回答

1

你能夠在調用這些方法之前先解析數值嗎?如果是這樣,您可以使用以下方法做到這一點

var provider = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone(); 
    provider.CurrencySymbol = "$"; 
    var x = decimal.Parse(
     "$1,200", 
     NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, 
     provider); 
+0

這個我認爲會很棒,作爲一個html幫手 – griegs 2009-11-22 23:28:50

+0

解析它通常不是問題,但我有一些「錢」字段,我寧願沒有我的控制器解析TryUpdateModel的垃圾,如果可能的話。 – 2009-11-23 01:15:51

+0

@cadmium使用自定義模型聯編程序,請參閱我的答案中的鏈接。 – eglasius 2009-11-25 16:14:27

2

答案被授予弗雷迪·里奧斯,因爲他的鏈接與底座要做到這一點給我提供了,但代碼需要一些固定起來:

// http://www.crydust.be/blog/2009/07/30/custom-model-binder-to-avoid-decimal-separator-problems/ 
public class MoneyParsableModelBinder : DefaultModelBinder 
{ 

    public override object BindModel(ControllerContext controllerContext, 
     ModelBindingContext bindingContext) 
    { 

     object result = null; 
     // Added support for decimals and nullable types - c. 
     if (
      bindingContext.ModelType == typeof(double) 
      || bindingContext.ModelType == typeof(decimal) 
      || bindingContext.ModelType == typeof(double?) 
      || bindingContext.ModelType == typeof(decimal?) 
      ) 
     { 

      string modelName = bindingContext.ModelName; 
      string attemptedValue = bindingContext.ValueProvider[modelName].AttemptedValue; 

      // Depending on cultureinfo the NumberDecimalSeparator can be "," or "." 
      // Both "." and "," should be accepted, but aren't. 
      string wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; 
      string alternateSeperator = (wantedSeperator == "," ? "." : ","); 

      if (attemptedValue.IndexOf(wantedSeperator) == -1 
       && attemptedValue.IndexOf(alternateSeperator) != -1) 
      { 
       attemptedValue = attemptedValue.Replace(alternateSeperator, wantedSeperator); 
      } 

      // If SetModelValue is not called it may result in a null-ref exception if the model is resused - c. 
      bindingContext.ModelState.SetModelValue(modelName, bindingContext.ValueProvider[modelName]); 

      try 
      { 
       // Added support for decimals and nullable types - c. 
       if (bindingContext.ModelType == typeof(double) || bindingContext.ModelType == typeof(double?)) 
       { 
        result = double.Parse(attemptedValue, NumberStyles.Any); 
       } 
       else 
       { 
        result = decimal.Parse(attemptedValue, NumberStyles.Any); 
       } 
      } 
      catch (FormatException e) 
      { 
       bindingContext.ModelState.AddModelError(modelName, e); 
      } 
     } 
     else 
     { 
      result = base.BindModel(controllerContext, bindingContext); 
     } 

     return result; 
    } 
} 

這是不漂亮,但它作品。