Asp.Net Core Localization Decimal Field Dot and Comma

ASP.NET Core localization decimal field dot and comma

After digging depth the problem I found two solution:

The comment from Stephen Muecke where explain how to add the required jquery to the input for a validation for comma and dot

A custom InputTagHelper where transform the comma into dot. Here I added only a decimal type but obviously you can add float and double.

[HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class InvariantDecimalTagHelper : InputTagHelper
{
private const string ForAttributeName = "asp-for";

private IHtmlGenerator _generator;

[HtmlAttributeName("asp-is-invariant")]
public bool IsInvariant { set; get; }

public InvariantDecimalTagHelper(IHtmlGenerator generator) : base(generator)
{
_generator = generator;
}

public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);

if (IsInvariant && output.TagName == "input" && For.Model != null && For.Model.GetType() == typeof(decimal))
{
decimal value = (decimal)(For.Model);
var invariantValue = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
output.Attributes.SetAttribute(new TagHelperAttribute("value", invariantValue));
}
}
}

For use this 2nd solution you simply add asp-is-invariant to your input, like this

 <input asp-for="AmountSw" class="form-control" asp-is-invariant="true" />

Accept comma and dot as decimal separator

Cleanest way is to implement your own model binder

public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue);
// of course replace with your custom conversion logic
}
}

And register it inside Application_Start():

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

Credits : Default ASP.NET MVC 3 model binder doesn't bind decimal properties

ASP Net Core decimal input with period turns into a whole number

nl-NL culture uses comma as decimal separator. You can override current culture`s number format for each request with this code

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
var currentThreadCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
currentThreadCulture.NumberFormat = NumberFormatInfo.InvariantInfo;

Thread.CurrentThread.CurrentCulture = currentThreadCulture;
Thread.CurrentThread.CurrentUICulture = currentThreadCulture;

await next();
});
...
}

Allow dot and comma in numbers, not only for decimal

I just found this answer.

Fixing binding to decimals

It worked perfectly in my scenario. This guy solved the exactly same problem I was having!

I just had modify a few lines of code, but the most important part was this line:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

I modified it to accept nullable values.

Comma vs dot as decimal separator

You should be using a parametrized query for inserting values. That means that you should only use parameter placeholders in your SQL string and add the actual values as query parameters.

This is generally a good practice to prevent SQL injection attacks. While those may be a lesser issue here, if all of your values are numerical (and possibly do not even come directly from user input), this parametrization also serves for ensuring that parameter values get formatted just like the target engine wants/needs them. Floating point numbers will be recognized without you having to worry about the correct decimal separator, and strings will be recognized without you having to worry about the correct quotation marks and escaping.

So, your INSERT statement should be changed as follows:

cmd.CommandText = "INSERT INTO valoresStock (Fecha, IdArticulo, IdColor, KgPorUnidad, Stock, CostePorKg, costePorUnidad)"
+ "VALUES (@fecha, @idArticulo, @idColor, @kgPorUnidad, @stock, @costePorKg, @costePorUnidad)";

Then, you can add your parameter values to the command like this:

cmd.Parameters.AddWithValue("@fecha", DateTime.Today.ToString(System.Globalization.CultureInfo.InvariantCulture));
cmd.Parameters.AddWithValue("@idArticulo", referencia.idArticulo);
cmd.Parameters.AddWithValue("@idColor", referencia.idColor);
cmd.Parameters.AddWithValue("@kgPorUnidad", referencia.kilos);
cmd.Parameters.AddWithValue("@stock", referencia.stockActual);
cmd.Parameters.AddWithValue("@costePorKg", referencia.valorPorKg);
cmd.Parameters.AddWithValue("@costePorUnidad", referencia.valorPorUnidad);

All the floating point values will then be automatically recognized for what they are and stored appropriately.

One thing to note is that I have explicitly converted DateTime.Today to a string for two reasons:

  • DateTime is not a primitive type, so I'm not entirely certain what the database engine would do to it.
  • You have declared the column Fecha as having type TEXT, so I presume you want a textual representation of the date in your database rather than anything which could be "evaluated".

In order to ensure that your program writes the same data, no matter on what machine it is executed, I have used the InvariantCulture CultureInfo instance, which provides, so-to-speak, a "neutral" format independent of the current machine's culture settings. If you also have the program expect this format in case you ever parse the date, the database files written by your application will always be compatible, even when the application is used across machines with different culture settings.

asp.net compare validators to allow comma and dot (both!) as decimal separator

I solved this by using a custom validator and writing the same logic in javascript for browser validation and in .net for validating once the postback is triggered.



Related Topics



Leave a reply



Submit