lew
lew

Reputation: 77

DataAnnotation DisplayFormat for decimal numbers

I've got his code. PartialView.

<div class="input width110">
    @Html.EditorFor(x => x.Price, @Html.Attributes(@class: "right_text_align", @disabled: "true", @id: "Price"))
</div>

Model.

public class ServiceModel
{
 [DisplayFormat(DataFormatString = "{0:0.00}", ApplyFormatInEditMode = true)]
 public decimal Price { get; set; }
}

Controller

public ActionResult SetService(ServiceModel model, string action)
{

            if (ModelState.IsValid)
            {
               /*Does smthg.*/
               ModelState.Clear(); 
            }

       return View("Index", rcpModel); 
       //Index is main view, which holds partialView
       //rcpModel holds, model
 }

When view loads Decimal is displayed in format "0.00". But after post when modelState is invalid number in displayed in format "0.0000". If model state isvalid, everything goes well. Has anyone encountered anything similar?

Upvotes: 1

Views: 6709

Answers (2)

Revious
Revious

Reputation: 8146

To display dot instead of comma is enough to change the culture to english in every point of the code which is used before the view is called.

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("En");

Upvotes: 0

amhed
amhed

Reputation: 3659

If you have javascript modifying the values on textboxes (currency formatting or commas) then you might be getting binding errors because it will behave as a string. Try this:

Create a BindingProperty for decimal values

public class DecimalModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
                            ModelBindingContext bindingContext)
    {
        var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        var modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try
        {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                                            CultureInfo.CurrentCulture);
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

On your global.asax app_start or WebActivator.PostApplicationStartMethod add an entry to register the custom binder:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

Upvotes: 1

Related Questions