美元货币的asp.net mvc验证注释

时间:2016-01-29 20:23:40

标签: asp.net asp.net-mvc

我正在验证Html.TextBoxFor。这是我在视图上的代码

@Html.TextBoxFor(m => m.Amount, new {@class = "form-control", Value = String.Format("{0:C}", Model.Amount) })

此代码从5000.00获取数据库中的double值,并在UI上显示为$ 5,000.00。但是,当用户点击提交按钮时,会显示验证错误

  

价值'$ 5,000.00'对金额无效。

我对模型的验证注释是

[Range(0, double.MaxValue, ErrorMessage = "Please enter valid dollar amount")]

要让它提交,我不得不重新输入5000.00。我怎样才能解决这个问题?感谢。

2 个答案:

答案 0 :(得分:1)

您可以创建自己的Binder对象来处理此问题。首先创建这个对象:

public class DoubleModelBinder : 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 (!string.IsNullOrEmpty(valueResult.AttemptedValue))
        actualValue = Convert.ToDouble(valueResult.AttemptedValue.Replace("$", ""), System.Globalization.CultureInfo.CurrentCulture);
    }
    catch (FormatException e)
    {
      modelState.Errors.Add(e);
    }

    if (bindingContext.ModelState.ContainsKey(bindingContext.ModelName))
      bindingContext.ModelState[bindingContext.ModelName] = modelState;
    else
      bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
    return actualValue;
  }
}

然后在Application_Start函数的Global.asax.cs文件中添加:

ModelBinders.Binders.Add(typeof(double?), new DoubleModelBinder());

答案 1 :(得分:1)

当您在htmlAttributes中执行value = string.Format("{0:C}", Model.Amount)时,razor将执行C#代码并返回值"$125.67",(假设您的Amount属性的值为{{1} })这是一个字符串。因此,您的视图生成的标记将为

125.67M

现在<input value="$125.67" class="form-control" id="Amount" name="Amount" type="text"> 不是一个valide十进制值,而是一个字符串。它无法将此文本框的值映射到视图模型的$125.67属性,该属性的类型为decimal / doube。

您可以做的是,在类型字符串的视图模型中创建一个新属性来存储此格式化的字符串值,当用户提交表单时,尝试将其解析回十进制变量并使用它。

因此,请在视图模型中添加新属性

Amount

在您看来,它是强类型的CreateOrderVm

public class CreateOrderVm
{
  public int Id { set;get;}
  public string AmountFormatted { set;get;}  // New property
  public decimal Amount  { set;get;}
}

在你的HttpPost行动中

@model CreateOrderVm
@using(Html.BeginForm())
{
    @Html.TextBoxFor(m => m.AmountFormatted, new { @class = "form-control",
                                Value = String.Format("{0:C}", Model.Amount) })

    <input type="submit" />
}