Home > front end >  Using ASP.NET Core MVC with .NET 6, number from input tag in a form is losing the decimal separator
Using ASP.NET Core MVC with .NET 6, number from input tag in a form is losing the decimal separator

Time:01-13

I was trying to create a form to add new items to my database, and my model includes a price. The type of the price is double, and the number input on my form has a step of .01 The issue is that when submitting my new item with the form, the number is losing the decimal separator, regardless of the lang attribute of the input tag, and so using a comma or dot doesn't make a difference. Because of this, 5.45 and 5,45 will both turn into 545.00 when written as a price on my item's list.

Here's my model:

public class Pizza 
{
    public Pizza(int id, string name, string description, double price, string pictureUrl) 
    {
        Id = id;
        Name = name;
        Description = description;
        Price = price;
        PictureUrl = pictureUrl;
    }

    public Pizza() { }

    [Key]
    public int Id { get; set; }
    
    [Required(ErrorMessage = "Il campo è obbligatorio.")]
    public string Name { get; set; }
    
    [Required(ErrorMessage = "Il campo è obbligatorio.")]
    public string Description { get; set; }
    
    [Required(ErrorMessage = "Il campo è obbligatorio.")]
    [Range(0, double.MaxValue, ErrorMessage = "Il prezzo non può essere negativo.")]
    public double Price { get; set; } // This is the property which is being set to the wrong value
    
    [Required(ErrorMessage = "Il campo è obbligatorio.")]
    public string PictureUrl { get; set; }
}

And here's the code for my controller's action:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult New(Pizza pizza) 
{
    if (!ModelState.IsValid) 
    {
        return View("New", pizza);
    }

    using (var db = new PizzasDbContext()) 
    {
        int modifications = db.AddPizza(pizza);
        Console.WriteLine(modifications);
    }

    return RedirectToAction("Index");
}

CodePudding user response:

Well, based on your code snippet, it's clear that, you have not defined the decimal precision for your Price property. thus, it cannot recognize decimal point. You should update your code in following way:

Pizza POCO Model:

    [Required]
    [Column(TypeName = "decimal(18, 2)")] // OR `[Precision(18, 2)]`
    public decimal Price { get; set; }

Note: this means Price would be a decimal number which would contains upto 18 main number along with 2 decimal precision after . point. Keep in mind that [Column(TypeName = "decimal(18, 2)")] and [Precision(18, 2)] act same. However, you can keep public double Price but annotation should be [Column(TypeName = "decimal(18, 2)")]

Database Schema Should be:

Price Decimal(18,2) NOT NULL

The above reason may causing your unexpected decimal result.

Note: For more details can be found in the official document here.

CodePudding user response:

Found a somewhat hacky solution that works for me. The issue is that the form on my view would always, at all times, return the decimal value with a dot. This is most likely a standard of HTML or JavaScript.

The solution was to force the server's thread to use a culture that uses a dot instead of a comma to represent doubles, as the value returned from the view is actually a string, and therefore when parsed would lose any dot or useless zeroes.

The code that worked for me is the following:

var cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencySymbol = "€";
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";

CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

I found the code on this StackOverflow post.

  • Related