我有一个运行非英语配置(西班牙语)的aspnet核心应用程序:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
......
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(new CultureInfo("es-AR"))
,SupportedCultures = new List<CultureInfo>
{
new CultureInfo("es-AR")
}
,SupportedUICultures = new List<CultureInfo>
{
new CultureInfo("es")
}
});
.........
}
在英语中,十进制数的小数部分用点分隔,但在西班牙语中使用逗号:
我在控制器中有这个动作:
[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建议的自定义模型绑定更改此行为。这是我的基于Custom Model Binding in 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());
});