Asp.Net MVC中帶有千位分隔符的十進制值
我有一個自定義模型類,其中包含一個小數成員和一個接受此類條目的視圖。在我添加 javascripts 來格式化輸入控制項中的數字之前,一切都執行良好。格式程式碼在焦點模糊時用千位分隔符’,‘格式化輸入的數字。
問題是我的模態類中的十進制值沒有用千位分隔符很好地綁定/解析。當我使用“1,000.00”對其進行測試時,ModelState.IsValid 返回 false,但它對“100.00”有效,沒有任何更改。
如果您對此有任何解決方案,可以與我分享嗎?
提前致謝。
樣本類
public class Employee { public string Name { get; set; } public decimal Salary { get; set; } }樣品控制器
public class EmployeeController : Controller { [AcceptVerbs(HttpVerbs.Get)] public ActionResult New() { return View(); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult New(Employee e) { if (ModelState.IsValid) // <-- It is retruning false for values with ',' { //Subsequence codes if entry is valid. // } return View(e); } }範例視圖
<% using (Html.BeginForm()) { %> Name: <%= Html.TextBox("Name")%><br /> Salary: <%= Html.TextBox("Salary")%><br /> <button type="submit">Save</button> <% } %>正如 Alexander 建議的那樣,我嘗試了使用 Custom ModelBinder 的解決方法。問題解決了。但該解決方案與 IDataErrorInfo 實現並不順利。由於驗證,當輸入 0 時,Salary 值變為空。請問有什麼建議嗎?Asp.Net MVC 團隊成員會來 stackoverflow 嗎?我能從你那裡得到一點幫助嗎?
按照 Alexander 的建議,使用自定義模型綁定器更新了程式碼
模型粘合劑
public class MyModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } ValueProviderResult valueResult; bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName, out valueResult); if (valueResult != null) { if (bindingContext.ModelType == typeof(decimal)) { decimal decimalAttempt; decimalAttempt = Convert.ToDecimal(valueResult.AttemptedValue); return decimalAttempt; } } return null; } }員工類
public class Employee : IDataErrorInfo { public string Name { get; set; } public decimal Salary { get; set; } #region IDataErrorInfo Members public string this[string columnName] { get { switch (columnName) { case "Salary": if (Salary <= 0) return "Invalid salary amount."; break; } return string.Empty; } } public string Error{ get { return string.Empty; } } #endregion }
我不喜歡上面的解決方案並想出了這個:
在我的自定義模型綁定器中,如果它是小數,我基本上將值替換為文化不變值,然後將其餘工作交給預設模型綁定器。作為一個數組的 rawvalue 對我來說似乎很奇怪,但這是我在原始程式碼中看到/偷來的。
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if(bindingContext.ModelType == typeof(decimal) || bindingContext.ModelType==typeof(Nullable<decimal>)) { ValueProviderResult valueProviderResult = bindingContext.ValueProvider[bindingContext.ModelName]; if (valueProviderResult != null) { decimal result; var array = valueProviderResult.RawValue as Array; object value; if (array != null && array.Length > 0) { value = array.GetValue(0); if (decimal.TryParse(value.ToString(), out result)) { string val = result.ToString(CultureInfo.InvariantCulture.NumberFormat); array.SetValue(val, 0); } } } } return base.BindModel(controllerContext, bindingContext); }
其背後的原因是,在 ValueProviderResult.cs 的 ConvertSimpleType 中使用了 TypeConverter。
十進制的 TypeConverter 不支持千位分隔符。在這裡閱讀:http ://social.msdn.microsoft.com/forums/en-US/clr/thread/1c444dac-5d08-487d-9369-666d1b21706e
我還沒有檢查,但在那篇文章中,他們甚至說沒有使用傳遞給 TypeConverter 的 CultureInfo。它永遠是不變的。
string decValue = "1,400.23"; TypeConverter converter = TypeDescriptor.GetConverter(typeof(decimal)); object convertedValue = converter.ConvertFrom(null /* context */, CultureInfo.InvariantCulture, decValue);所以我想你必須使用一種解決方法。不太好…