1

I'm having some problems with Web.API and cultures.

For example (more elaborate example below) The client sends the number: 500.000 and it gets interpreted as five hunderd instead of five hunderd thousand.

I've come across this problem with Windows Forms applications. There i would just set the culture for the thread. But using Web.Api (which is totally new to me) i needed to change my tactic.

My searches have supplied me with several promising solutions but none seem to work sofar.Any got any pointers for me or could point me to the correct solution?

Some examples used:

Solution 1: In the web.config of the webservice: supply the culture under system.web

<system.web>
  <globalization enableClientBasedCulture="false" culture="nl-BE" uiCulture="nl-BE"/>
</system.web>

Solution 2: In the construtor of my controller

    CultureInfo ci = new CultureInfo("nl-BE");
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;

Solution 3: Editing global.asax Used the solution mentionned here but no dice.

or

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        CultureInfo newCulture = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
        newCulture.NumberFormat.NumberDecimalSeparator = ",";
        newCulture.NumberFormat.NumberGroupSeparator = ".";
        Thread.CurrentThread.CurrentCulture = newCulture; 
        Thread.CurrentThread.CurrentUICulture = newCulture; 
    }

Some code:

The object:

    public class Book
    {
         public String Author {get; set;}
         public String Title {get; set;}
         public Double Price {get; set;}
    }

The Json sent by the client:

     { "Author": "User09","Title": "User09 The biography", "Price":"50,39" }

     => With the meaning of 50 euros and 39 cents

The function:

    [HttpPost]
    public String StoreNewObject(Book myBook)
    {
          // myBook.Price already contains 5039.0 (as in 5039 euros and 0 cents) here before the first line of code is executed.
          ...
    }

My dwindeling patience thanks the.

Note: The application is limited to .Net 4.0

Note 2: Found one working (Ugly Solution) Changed my model as follows:

    public class Book
    {
         public String Author {get; set;}
         public String Title {get; set;}
         public String Price {
                get { return  PriceValue.ToString();
                set {
                CultureInfo ci = new CultureInfo("nl-BE");
                PriceValue = Math.Round(Convert.ToDouble(value, ci),2);
                }
        }
         public Double PriceValue {get; set;}
    }

In this case PriceValue will contain the correct value.

Community
  • 1
  • 1
User999999
  • 2,500
  • 7
  • 37
  • 63
  • 1
    In Solution 3 you are creating a clone of the culture, set the separators but never use the clone. Try adding Thread.CurrentThread.CurrentCulture = newCulture; Thread.CurrentThread.CurrentUICulture = newCulture; to solution 3 – user469104 Feb 19 '15 at 13:57
  • @user469104: nicely noted. But adding it didn't resolve the problem for me! – User999999 Feb 19 '15 at 13:58
  • If you are using .NET 4.5 you could try using CultureInfo.DefaultThreadCurrentCulture as specified in this solution, http://stackoverflow.com/questions/468791/is-there-a-way-of-setting-culture-for-a-whole-application-all-current-threads-a – user469104 Feb 19 '15 at 14:06
  • @user469104. I've come across that solution aswell. Unfortunatly i'm limited to .net 4.0. I will add it to the question? – User999999 Feb 19 '15 at 14:10

1 Answers1

3

The JSON submitted by your client is not valid JSON. JSON is based on JavaScript syntax and floating point numbers uses dot and not comma as the decimal separator. From json.org:

JSON number

I overlooked the fact that the value is enclosed in quotes and thus is a valid JSON string. Apparently, Web API tries to convert the string into a number using CultureInfo.InvariantCulture during model binding. There are various ways to customize how a request is mapped to a model and using a model binder may allow you to customize how strings are converted to numbers.

Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
  • Martin thank you for your insight. But according the JSON parsers on our beloved web, it is valid JSON. But your remark did give me a new idea to try. – User999999 Feb 19 '15 at 14:16
  • nice scheme!!!! Could it be though that the JSON is correct because the value (my double) is encapsulated by quotes? – User999999 Feb 19 '15 at 14:32
  • @User999999: It is clearly stated on http://www.json.org/ that numbers can contain a dot but not a comma. But parsers are often foregiving explaining why both "the JSON parsers on our beloved web" as well as Web API parses the number. The problem is that the result of the parse is not what you expect. – Martin Liversage Feb 19 '15 at 14:33
  • @User999999: If the value is enclosed in quotes then it is a string and then it is valid JSON. But then I would expect the data type on the server side to also be a string. In that case you can parse the string on the server side using whatever method you prefer (including using a specific `CultureInfo`). – Martin Liversage Feb 19 '15 at 14:35