1

I had an entity :

public class Book
{
public int BookID{get; set;}
public string BookName{get; set;}
public int Price {get; set;}
}

I scaffolded and created Controller and Views automatically. Then I changed my entity to this :

public class Book
{
public int BookID{get; set;}
public string BookName{get; set;}
public double Price {get; set;}
}

I copied my project, then deleted controller and views, recreated them automatically. Then copied the content of controller and views from the old one. Now when I enter 18.75 I get "The value '18.75' is not valid for Price." error. How can I fix this situation? Thanks.

7
  • 1
    Enter "18,75", seems problem in current culture and decimal separator Commented Jan 23, 2015 at 14:14
  • 3
    You should use decimal for currency, not double. Commented Jan 23, 2015 at 14:14
  • @IgorSemin When I enter "18.75", I get : "The field Price must be a number." I changed Price to decimal btw. Commented Jan 23, 2015 at 14:23
  • it's no matter, 18.75 correct value for decimal and double, need check decimal separator in regional setting for server Commented Jan 23, 2015 at 14:44
  • 1
    AFAIK Turkey is using the comma as the decimal separator. Either use a comma, switch to English or use my answer below... Commented Jan 23, 2015 at 15:08

2 Answers 2

1

Anyhow. I' avoiding this in the meantime by handling decimal input (mostly) independent on regional settings by having my own decimal handler:

  1. in Startup/FilterConfig.cs:

    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
    
  2. A new class DecimalModelBinder:

    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
        {
            actualValue = GeneralHelper.ToDecimal(valueResult.AttemptedValue);
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }
    
        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
      }
    }
    

    The function GeneralHelper.ToDecimal() is based on the following blog entry: https://sreindl.wordpress.com/2013/10/26/i18n-parsing-decimal-values/

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer. A dummy question : I should place DecimalModelBinder class inside App_Start, right? And should I do anything else in Controller or Views? Thank you.
I usually create a folder "Filters" (if not automatically created by Visual Studio) and place those filter classes there (I have a couple of them especially for table and regional number / date handling...)
1

If the culture on your server handles decimal numbers with a comma, you also need to tell jQuery validation that it should be using comma's as decimal separators. You can take a look at this blog-post (a bit old but the stuff still works) for a general approach on handling the culture. The code here does the magic:

$(document).ready(function () {
    //Ask ASP.NET what culture we prefer, because we stuck it in a meta tag
    var data = $("meta[name='accept-language']").attr("content")
    //Tell jQuery to figure it out also on the client side.
    $.global.preferCulture(data);

    //Tell the validator, for example,
    // that we want numbers parsed a certain way!
    $.validator.methods.number = function (value, element) {
        if ($.global.parseFloat(value)) {
            return true;
        }
        return false;
    }
});

Note that the link to the jQuery globalization plugin is dead. It has been moved.

Basically you have to override the default number validation. I know that sucks but I yet have to find an approach as clean as this one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.