Aspnet Core 十进制绑定不适用于非英语文化 [英] Aspnet Core Decimal binding not working on non English Culture

查看:15
本文介绍了Aspnet Core 十进制绑定不适用于非英语文化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用非英语配置(西班牙语)运行的 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 十进制绑定不适用于非英语文化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆