My regional settings use a comma symbol as a decimal number separator. It doesn't work with the default validator, so I had to adapt your example and redefine the jQuery Validation rule.
public class DecimalBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
var modelType = context.Metadata.UnderlyingOrModelType;
if (modelType == typeof(decimal) || modelType == typeof(decimal?))
return new BinderTypeModelBinder(typeof(DecimalBinder));
return null;
}
}
public class DecimalBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueResult == ValueProviderResult.None)
return Task.CompletedTask;
decimal result;
if (valueResult.FirstValue != string.Empty)
{
// try current culture
if (!decimal.TryParse(valueResult.FirstValue, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
// then try in US culture
!decimal.TryParse(valueResult.FirstValue, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
// finally try neutral culture
!decimal.TryParse(valueResult.FirstValue, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "You should provide a valid decimal value");
return Task.CompletedTask;
}
bindingContext.Result = ModelBindingResult.Success(result);
}
else if (!bindingContext.ModelMetadata.IsNullableValueType)
{
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Decimal value is non-nullable and can't be empty");
}
return Task.CompletedTask;
}
}
builder.Services.AddRazorPages().AddViewOptions(options =>
{
options.ModelBinderProviders.Insert(0, new DecimalBinderProvider());
});
Put the below code into the "/wwwroot/js/number-validator-override.js" and link it in "_ValidationScriptsPartial.cshtml" after the <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> line.
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
My regional settings use a comma symbol as a decimal number separator. It doesn't work with the default validator, so I had to adapt your example and redefine the jQuery Validation rule.
Put the below code into the "/wwwroot/js/number-validator-override.js" and link it in "_ValidationScriptsPartial.cshtml" after the
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>line.