I've been looking for a solution to this case for hours, and I did not find anything that worked out for me.
Here we use the comma for decimal separator, and when I send a value like "15,50", in my controller I get the value of the model as "1550", and it only makes sense if I send "15.50".
I covered the following topics, and nothing worked.
Set CultureInfo in Asp.net Core to have a . as CurrencyDecimalSeparator instead of ,
Aspnet Core Decimal binding not working on non English Culture
I am sending the form with ajax, using the $form.serializeArray()
as below:
function getFormData(xform) {
var $form = $('#' + xform);
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
});
return indexed_array;
}
send:
function PostFormAjax(controller, metodo, params, redir, divacao, reloadgrid) {
if (params != null) {
var formData = new FormData();
var json = $.parseJSON(JSON.stringify(params));
$(json).each(function (i, val) {
$.each(val, function (k, v) {
console.log(k + " : " + v);
formData.append(k, v);
});
});
}
$.ajax({
url: '/' + controller + '/' + metodo,
data: JSON.stringify(params),
contentType: 'application/json',
type: 'POST',
success: function (data) {
AjaxFim(metodo, data, redir, divacao, reloadgrid);
}
});
}
My controller:
[HttpPost]
public IActionResult GravaProduto([FromBody] Produtos produto)
{
if (ModelState.IsValid)
{
//produto.Valorcusto is 1550 and not 15,50 as it was posted
//produto.Valorvenda is 1550 and not 15,50 as it was posted
}
}
My Model.cs
public partial class Produtos
{
public int Cod { get; set; }
public string Descricao { get; set; }
public decimal Valorcusto { get; set; }
public decimal Valorvenda { get; set; }
}
I tried to make a replace in formData.append(k, v.replace(',', '.'));
and also does not work, I also would not know which field is a decimal.
What do I have to do? because I'm lost, what should have been simpler became more complicated.
What I did to keep working until I found a solution was:
Wear a mask according to my regional setting:
$('.stValor').mask("#.###.##0,00", { reverse: true });
And before posting the form, I switch to the accepted formatting:
$('#fCadAltProd').validator().on('submit', function (e) {
if (e.isDefaultPrevented()) {
} else {
e.preventDefault();
$('.stValor').mask("#,###,##0.00", { reverse: true });
//Ajax post here
}
});
Here we use the comma for decimal separator, and when I send a value like "15,50", in my controller I get the value of the model as "1550", and it only makes sense if I send "15.50".
Create a custom model binder using the Norwegian culture, because Norway also uses the comma decimal separator. You might also want to specify certain multiple allowed number styles.
Here is one that still needs to have error handling. It gives you the basic idea, though, and you can build on it from here. What I would do it copy most of the logic from the built-in DecimalModelBinder
.
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.Logging;
namespace AspNetCorePlayground.Models
{
public class MyFirstModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext
.ValueProvider
.GetValue(bindingContext.ModelName);
var cultureInfo = new CultureInfo("no"); // Norwegian
decimal.TryParse(
valueProviderResult.FirstValue,
// add more NumberStyles as necessary
NumberStyles.AllowDecimalPoint,
cultureInfo,
out var model);
bindingContext
.ModelState
.SetModelValue(bindingContext.ModelName, valueProviderResult);
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
}
Then decorate your class like this:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
namespace AspNetCorePlayground.Models
{
public class MyFirstModelBinderTest
{
[ModelBinder(BinderType = typeof(MyFirstModelBinder))]
public decimal SomeDecimal { get; set; }
}
}
I tested it on a controller:
[HttpGet("test")]
public IActionResult TestMyFirstModelBinder(MyFirstModelBinderTest model)
{
return Json(model);
}
This is the result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With