weldsonandrade
weldsonandrade

Reputation: 626

Asp.net mvc 4 getting decimal value instead integer

I have a class like:

public class Item
{
    public int ItemID { get; set; }

    [Display(Name = "Value")]
    [Column(TypeName = "money")]
    public decimal Value{ get; set; }
}

In the form I enter 12.50 and in my post Action the object has Item.Value = 1250 when should have 12.50, How to fix this?

The Action Method:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Item item)
{
    ...code...
}

View:

<div class="editor-label">
    @Html.LabelFor(model => model.Value)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Value)
    @Html.ValidationMessageFor(model => model.Value)
</div>

When type 12. the validation client side say 'The field Valor must be a number.' however let me execute post action method, with 12, say the same thing but don't let me.

Upvotes: 0

Views: 1685

Answers (2)

weldsonandrade
weldsonandrade

Reputation: 626

I solved with custom bind thanks a Phil Haack (http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx). I modified the DecimalModelBind class to:

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
            {
                var value = valueResult.AttemptedValue.Replace('.', ',');
                actualValue = Convert.ToDecimal(value,
                    CultureInfo.CurrentCulture);
            }
            catch (FormatException e)
            {
                modelState.Errors.Add(e);
            }
            if (bindingContext.ModelState[bindingContext.ModelName] == null)
            {
                bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
            }
            return actualValue;
        }
    }

I added these lines:

var value = valueResult.AttemptedValue.Replace('.', ',');
if (bindingContext.ModelState[bindingContext.ModelName] == null)

The First one to replace ',' by '.' and the second one to check if don't have a ModelState with the same name avoiding exception.

Upvotes: 2

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

Try specifying a Culture on the server that will use . as decimal separator such as:

<globalization uiCulture="en-US" culture="en-US" />

Alternatively if you want to use auto culture (i.e. infer from the client browser settings and the Accept-Language request header) then you could write a custom model binder for the decimal type and use the [DisplayFormat] attribute to explicitly set the desired format. I have illustrated this at the following post: https://stackoverflow.com/a/11272982/29407 (it's for the DateTime type but you could trivially easy adapt the example for the decimal type as well)

Upvotes: 0

Related Questions