Aspnet核心十进制绑定不适用于非英语文化

我有一个运行非英语配置(西class牙语)的aspnet核心应用程序:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { ...... app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture(new CultureInfo("es-AR")) ,SupportedCultures = new List { new CultureInfo("es-AR") } ,SupportedUICultures = new List { new CultureInfo("es") } }); ......... } 

在英语中,十进制数的小数部分用点分隔,但在西class牙语中使用逗号:

  • 10256.35英语
  • 10256,35西class牙语

我在控制器中有这个动作:

  [HttpPost] public decimal Test(decimal val) { return val; } 

如果我使用邮递员并向该行动发送一个类似于{val:15.30}的json,则该动作中的val将返回0(由于文化而绑定不起作用)。 如果我发送这样的json {val:15,30}然后在我回忆的动作中15.30我遇到的问题是,我需要动作接受带逗号的小数,因为这是来自输入类型文本的格式应用程序的表单。 但我还需要接受带有来自json格式请求的点的十进制。 无法在json中指定接受逗号的十进制/浮点数(将其作为字符串发送不是一个选项)。 我怎样才能做到这一点??? 我为此疯狂。

谢谢!!

显然,ASP.NET核心1.0.0中的十进制绑定默认情况下不是文化不变量。 模型绑定取决于服务器文化。

您可以使用Stephen Muecke建议的自定义模型绑定更改此行为。 这是我的基于ASP.Net Core 1.0(RTM)中的自定义模型绑定

 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?))) { return new InvariantDecimalModelBinder(context.Metadata.ModelType); } return null; } } public class InvariantDecimalModelBinder : IModelBinder { private readonly SimpleTypeModelBinder _baseBinder; public InvariantDecimalModelBinder(Type modelType) { _baseBinder = new SimpleTypeModelBinder(modelType); } 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); } } 

在Startup.cs中:

 services.AddMvc(config => { config.ModelBinderProviders.Insert(0, new InvariantDecimalModelBinderProvider()); });