asp.net mvc validation annotation for dollar currency

后端 未结 2 870
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-22 03:01

I am validation for Html.TextBoxFor. Here is my code on the view

@Html.TextBoxFor(m => m.Amount, new {@class = \"form-control\", Value = Stri         


        
相关标签:
2条回答
  • 2020-12-22 03:18

    When you do the value = string.Format("{0:C}", Model.Amount) in the htmlAttributes, razor will execute the C# code and return the value,"$125.67", (Assuming the value of your Amount property is 125.67M) which is a string. So the markup generated by your view will be

    <input value="$125.67" class="form-control" id="Amount" name="Amount" type="text">
    

    Now since $125.67 is not not a valide decimal value, but a string. it cannot map the value of this textbox to the Amount property of your view model which is of type decimal/doube.

    What you can do is, create a new property in your view model of type string to store this formatted string value and when user submits the form, try to parse it back to a decimal variable and use it.

    So add a new property to your view model

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

    And in your view, which is strongly typed to CreateOrderVm

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

    And in your HttpPost action

    [HttpPost]
    public ActionResult Create(CreateOrderVm model)
    {
        decimal amountVal;
    
        if (Decimal.TryParse(vm.AmountFormatted, NumberStyles.Currency,
                                                 CultureInfo.CurrentCulture, out amountVal))
        {
            vm.Amount = amountVal;
        }
        else
        {
           //add a Model state error and return the model to view,
        }
    
        //vm.Amount has the correct decimal value now. Use it to save
        // to do  :Return something
    }
    
    0 讨论(0)
  • 2020-12-22 03:23

    You can create you own Binder object to handle this. First create this object:

    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;
      }
    }
    

    Then in your Global.asax.cs file in the Application_Start function, add this:

    ModelBinders.Binders.Add(typeof(double?), new DoubleModelBinder());
    
    0 讨论(0)
提交回复
热议问题