在ASP.NET Core MVC中,小数的模型绑定不接受千位分隔符

Ali*_*eza 1 c# model-binding asp.net-core-mvc

对于具有decimal属性的模型,如果来自客户端的值包含逗号作为千位分隔符,则模型绑定将失败。

我们该如何解决呢?任何解决方案(全局上,控制器/操作本地或模型/属性本地)都是好的。

我有一个解决方法,那就是拥有一个string可以读写的属性decimal。但我正在寻找更清洁的解决方案。

Ism*_*sma 5

如果您的应用程序仅需要支持特定格式(或区域性),则可以在您的Configure方法中按以下方式指定它:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var cultureInfo = new CultureInfo("en-US");
    cultureInfo.NumberFormat.NumberGroupSeparator = ",";

    CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

   [...]
}
Run Code Online (Sandbox Code Playgroud)

如果要支持多种文化并为每个请求自动选择正确的文化,则可以改用本地化中间件,例如:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    [...]  

    var supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es"),
    };

    app.UseRequestLocalization(new RequestLocalizationOptions
    {
        DefaultRequestCulture = new RequestCulture("en-US"),
        // Formatting numbers, dates, etc.
        SupportedCultures = supportedCultures,
        // Localized UI strings.
        SupportedUICultures = supportedCultures
    });

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)

此处的更多信息:https : //docs.microsoft.com/zh-cn/aspnet/core/fundamentals/localization?view=aspnetcore-2.2

编辑-小数活页夹

如果以上所有操作均失败,您也可以滚动自己的模型活页夹,例如:

public class CustomBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (context.Metadata.ModelType == typeof(decimal))
        {
            return new DecimalModelBinder();
        }

        return null;
    }
}

public class DecimalModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (valueProviderResult == null)
        {
            return Task.CompletedTask;
        }

        var value = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(value))
        {
            return Task.CompletedTask;
        }

        // Remove unnecessary commas and spaces
        value = value.Replace(",", string.Empty).Trim();

        decimal myValue = 0;
        if (!decimal.TryParse(value, out myValue))
        {
            // Error
            bindingContext.ModelState.TryAddModelError(
                                    bindingContext.ModelName,
                                    "Could not parse MyValue.");
            return Task.CompletedTask;
        }

        bindingContext.Result = ModelBindingResult.Success(myValue);
        return Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在您的ConfigureServices方法中注册自定义资料夹:

 services.AddMvc((options) =>
 {
     options.ModelBinderProviders.Insert(0, new CustomBinderProvider());
 });
Run Code Online (Sandbox Code Playgroud)

现在,每次在任何模型中使用十进制类型时,都会由自定义绑定程序进行解析。