Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alexkuznetsov/f01cd2f33dea34c410cee854eab7dce3 to your computer and use it in GitHub Desktop.
Save alexkuznetsov/f01cd2f33dea34c410cee854eab7dce3 to your computer and use it in GitHub Desktop.
Dotnet core decimal model binder problem fix
using System;
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
namespace BA.ECommerce.Client.Utility
{
public class InvariantDecimalModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (!context.Metadata.IsComplexType && (context.Metadata.ModelType == typeof(decimal) || context.Metadata.ModelType == typeof(decimal?)))
{
var loggerFactory = context.Services.GetService<ILoggerFactory>();
return new InvariantDecimalModelBinder(context.Metadata.ModelType, loggerFactory);
}
return null;
}
}
public class InvariantDecimalModelBinder : IModelBinder
{
private readonly SimpleTypeModelBinder _baseBinder;
public InvariantDecimalModelBinder(Type modelType, ILoggerFactory loggerFactory)
{
_baseBinder = new SimpleTypeModelBinder(modelType, loggerFactory);
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext));
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult != ValueProviderResult.None)
{
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
var valueAsString = valueProviderResult.FirstValue;
decimal result;
// Use invariant culture
if (decimal.TryParse(valueAsString, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out result))
{
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
}
// If we haven't handled it, then we'll let the base SimpleTypeModelBinder handle it
return _baseBinder.BindModelAsync(bindingContext);
}
}
}
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new InvariantDecimalModelBinderProvider());
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment