問題描述
我有一個使用非英語配置(西班牙語)運行的 aspnet 核心應用程序:
I have an aspnet core app that runs with a non english configuration (spanish):
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")
}
});
.........
}
在英語中,十進制數的小數部分用點分隔,但在西班牙語中使用逗號:
In english a decimal number has its decimal part delimited with a dot, but in spanish a comma is used:
- 10256.35 英文
- 10256,35 西班牙語
我在控制器中有這個動作:
I have this action in a controller:
[HttpPost]
public decimal Test(decimal val)
{
return val;
}
如果我使用郵遞員并向該操作發送一個像 {val: 15.30} 這樣的 json,那么操作中的 val 會收到 0(由于文化,綁定不起作用).如果我發送這樣的 json {val: 15,30} 然后在操作中我收到 15.30我遇到的問題是,我需要接受帶逗號的小數的操作,因為這是來自應用程序表單中輸入類型文本的格式.但我還需要接受帶有來自 json 格式請求的點的小數.無法在接受逗號的 json 中指定小數/浮點數(不能將其作為字符串發送).我怎樣才能做到這一點???我快把自己逼瘋了.
If I use postman and send to that action a json like this {val: 15.30}, then val in the action recives a 0 (binding not working because of the culture). If I send a json like this {val: 15,30} then in the action I recive 15.30 The problem I have is, I need the action to accept decimals with commas, because that is the format that comes from inputs type text in the app's forms. But i also need to accept decimal with a dot that comes from request in json format. There is no way to specify a decimal/float in json that accepts a comma (send it as string is not an option). How can I do this??? I'm driving my self crazy with this.
謝謝!!
推薦答案
顯然,ASP.NET core 1.0.0 中的十進制綁定默認不是文化不變的.模型綁定取決于服務器文化.
Apparently, the decimal binding in ASP.NET core 1.0.0 is not culture invariant by default. The model binding depends on the server culture.
您可以按照 Stephen Muecke 的建議使用自定義模型綁定來更改此行為.這是我的基于 自定義模型綁定在 ASP.Net核心 1.0 (RTM)
You can change this behavior with a custom model binding as suggested by Stephen Muecke. Here is mine based on 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 中:
And in Startup.cs:
services.AddMvc(config =>
{
config.ModelBinderProviders.Insert(0, new InvariantDecimalModelBinderProvider());
});
這篇關于Aspnet Core 十進制綁定不適用于非英語文化的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!