MVC4,Code First,C#项目
当使用显式值或从表中填充money字段时,TextBoxFor会显示带有2个小数位的值。如果该字段是从另一个类的货币字段填充的,则显示4个小数位。
public class Class1
{
[Column(TypeName = "money")]
public decimal Field1 { get; set; }
}
public class Class2
{
[Column(TypeName = "money")]
public decimal Field1 { get; set; }
}
public class Table1
{
public int Id { get; set; } public decimal Value { get; set; }
}
情景1:
Class1.Field1 = 14.95M;
情景2:
Class2.Field1 = Table1.Value;
情景3:
Class1.Field1 = Class2.Field1
查看
@Html.TextBoxFor(m => m.Class1.Field1, new { style = "width:70px;" })
对于场景1& 2 TextBoxFor正确显示2个小数位,使用方案3,它在编辑框中显示4个小数位。我需要使用TextBoxFor,所以我可以传递html属性。
Class2的实例本身是从Class2生成的Table中的值预先填充的。我已经使用SSMS检查了所有内容[表中的所有适用字段都是(money,not null)]并且在调试中找不到任何差异。
为什么TextBoxFor错误地显示场景3的货币格式(我知道SQL存储小数点后4位小数)?
更重要的是,如何让我的编辑框始终显示2位小数的货币值?
答案 0 :(得分:0)
在我的MVC应用中,我希望文本框显示为$4.95
。我使用了编辑模板。
@if(Model != null && Model.GetType() == typeof(string))
{
@Html.TextBox(
"",
string.Format("{0:c}", (decimal)decimal.Parse(Model))
)
}
@if(Model != null && Model.GetType() == typeof(decimal))
{
@Html.TextBox(
"",
string.Format("{0:c}", (decimal) Model),new {@class="no-number-validation"}
)
}
@if(Model == null)
{
@Html.TextBox("",null,new {@class="no-number-validation"})
}
然后显然我希望能够将$4.95
发送回服务器并让Model Binder自动处理它。此示例也处理%符号。
public class DecimalModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
if (valueResult.AttemptedValue.StartsWith("$"))
{
actualValue = decimal.Parse(valueResult.AttemptedValue, NumberStyles.Currency);
}
if (valueResult.AttemptedValue.EndsWith("%"))
{
actualValue = decimal.Parse(valueResult.AttemptedValue.Replace("%", "").Trim(),
CultureInfo.CurrentCulture);
}
if (actualValue == null)
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
这很好,因为我不必使用字符串作为货币文本框的属性类型来处理$符号。当对象被填充时,没有货币符号,并且值被分配到小数类型中。
答案 1 :(得分:0)
你可以舍入到2位小数(原始值是2位小数,所以我不担心舍入错误)。
decimal.Round(Value, 2)
Class1.Field1 = decimal.Round(Class2.Field1,2)
然后可以通过扩展方法实现。
public static decimal dR2(this decimal ip) { return decimal.Round(ip, 2); }
Class1.Field1 = Class2.Field1.dR2();