Search code examples
c#model-view-controllerdecimalformcollection

MVC FormCollection value parse to decimal with period seperator for decimals


This time I'm working on a small MVC application. In the update part of my model in the controller, all the field values are passed through in the controller. One of the fields is a decimal value. This value is stored in de the DB using the period as a separator. The field is named ContractHours. 40 is stored as 40.00. Now when retrieving the data the value in the form is showed as 40,00 due to the language setting of my browser (which is fine btw). But when I try to update, this value is passed to the formcollection is also 40,00 of course. But when I try to execute the update statement

update Employee set ContractHours = collection["ContractHours"] WHERE ID = 1

I get an exception because the DB doesn't accept 40,00 to pass as a decimal value. So I tried to parse the value as a decimal using:

var ch = Decimal.Parse(collection["ContractHours"],CultureInfo.InvariantCulture)

and even

var ch = Decimal.Parse(collection["ContractHours"], NumberStyles.Any, new CultureInfo("en-US"))

But both these statements return the value 40,00 as 4000.

using a simple replace does the trick, but it doesn't feel right

var ch = collection["ContractHours"].Replace(",",".");

I have searched this forum en googled for a solution, but I cannot find any. So what would be the right way to solve the problem without changing my browser's language settings?


Solution

  • Today I got in contact with someone who assisted me with this issue.

    It turned out when I used:

    var ch = Decimal.Parse(collection["ContractHours"], NumberStyles.Any,new CultureInfo("nl-NL"));
    

    Gave me the correct value for the ch var, in this case 40.00.

    However, another problem arose, and this is not part of the original question, but I thought I would share it anyway.

    I used the ch var in the query-string as shown below:

    string sqlQuery = $"update Employee set Name ='{collection["name"]}' , Email = ' {collection["email"]}'," +
                        $"ContractHours={ch},IsActive={(collection["IsActive"].ToString().Contains("true") ? 1 : 0)} " +
                        $"WHERE ID={id}";
    

    When I tried to execute this string, an exception was thrown. It turned out that the value of ch was again 40,00 when used in the query-string. I was told that this was caused by the conversion of the var ch to a string and when this happened the value used as the set culture is used. In this case, nl-NL causing the value of ch to change back to 40,00 when used in a string as in the SQL-query.

    So what we did is we added the next lines in the global.asx.cs of the MVC .NET Framework application in the Applicaiton_OnStart()

     CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;
     CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
     CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
     CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
    

    Then changed the sql-query to:

    string sqlQuery = $"update Employee set Name ='{collection["name"]}' , Email = ' {collection["email"]}'," +
                        $"ContractHours={collection["ContractHours"]},IsActive={(collection["IsActive"].ToString().Contains("true") ? 1 : 0)} " +
                        $"WHERE ID={id}";
    

    There was no need for the var ch anymore. I know the answer answers more than I asked for, but I just added this information, to clarify and I hope someone else can benefit from this.