2016-09-28 32 views
7

我有一個非英語配置(西班牙語)中運行的ASPNET核心應用: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") 
      } 
     }); 

     ......... 
    } 

英語的十進制數有其小數部分用點分隔的,但在西班牙語使用逗號:

  • 10256.35英語
  • 10256,35西班牙語

我有一個控制器,這個動作:

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

如果我使用郵遞員,發送到行動JSON像這樣{VAL:15.30},然後VAL在行動收到
0(綁定不是因爲工作文化)。如果我發送像這樣的json {val:15,30},那麼在我收回的操作中15.30 我遇到的問題是,我需要使用逗號接受小數的操作,因爲這是來自輸入的格式輸入文本該應用的形式。但是我還需要接受來自json格式請求的小數點。沒有辦法在接受逗號的json中指定一個十進制/浮點數(將其作爲字符串發送不是選項)。我怎樣才能做到這一點???這讓我瘋狂。

謝謝!

+0

您將需要創建一個自定義模型綁定器,讀取'contentType'和解析取決於內容類型 –

+0

的價值MVC5我使用了一個自定義模型綁定器,它解決了我的問題,對於mvc核心,您可能會在這裏找到類似的解決方案[ASP.Net Core 1.0(RTM)中的自定義模型綁定](http://intellitect.com/custom-model-binding -in-asp-net-core-1-0 /) – Ziyad

回答

8

顯然,默認情況下,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()); 
}); 
+1

這個複製/粘貼只會停止綁定負數。爲了避免在decimal.TryParse中添加numberStyles.AllowLeadingSign樣式。非常感謝 – adopilot

+0

編輯添加NumberStyles.AllowLeadingSign。趕上@adopilot –