C# 小数点后两位的货币编辑框
MVC4,代码优先,C#项目 当使用显式值或从表读取值填充货币字段时,TextBoxFor将显示带2位小数的值。如果该字段是从另一个类中的货币字段填充的,则显示4位小数C# 小数点后两位的货币编辑框,c#,razor,public,C#,Razor,Public,MVC4,代码优先,C#项目 当使用显式值或从表读取值填充货币字段时,TextBoxFor将显示带2位小数的值。如果该字段是从另一个类中的货币字段填充的,则显示4位小数 public class Class1 { [Column(TypeName = "money")] public decimal Field1 { get; set; } } public class Class2 { [Column(TypeName = "money")]
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
看法
对于方案1和方案2,TextBoxFor正确显示2位小数,而方案3则在编辑框中显示4位小数。我需要使用TextBoxFor,以便传递html属性
Class2的实例本身是根据Class2生成的表中的值预先填充的。我已经用SSMS[表中所有适用的字段都是(money,notnull)]和debug检查了所有内容,没有发现任何差异
为什么TextBoxFor不正确地显示场景3的货币格式(我知道SQL存储的小数精度为4)
更重要的是,如何让我的编辑框始终以2位小数显示货币值?在我的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;
}
}
这很好,因为我不必使用字符串作为货币文本框的属性类型来处理$符号。填充对象时,没有货币符号,值被分配到十进制类型。您可以舍入到2位小数(原始值是2位小数精度,因此我不担心舍入错误) 然后可以通过扩展方法实现它
public static decimal dR2(this decimal ip) { return decimal.Round(ip, 2); }
Class1.Field1 = Class2.Field1.dR2();
谢谢,尼克。这可能都管用,但我想出了一个简单得多的解决办法。请看我的答案。
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();