gpt4 book ai didi

c# - 在 asp.net core mvc 中,小数的模型绑定(bind)不接受千位分隔符

转载 作者:太空宇宙 更新时间:2023-11-03 19:40:26 24 4
gpt4 key购买 nike

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

我们如何解决这个问题?任何解决方案(全局、 Controller /操作本地或模型/属性本地)都是好的。

我有一个变通方法,它有一个 string 属性,可以读取和写入 decimal 属性。但我正在寻找更清洁的解决方案。

最佳答案

如果您的应用程序只需要支持特定格式(或文化),您可以在 Configure 方法中指定它,如下所示:

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

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

[...]
}

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

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();
}

更多信息在这里:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.2

编辑 - 十进制 Binder

如果上面的一切都失败了,你也可以推出你自己的模型 Binder ,例如:

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;
}
}

不要忘记在您的 ConfigureServices 方法中注册自定义绑定(bind)器:

 services.AddMvc((options) =>
{
options.ModelBinderProviders.Insert(0, new CustomBinderProvider());
});

现在,每次您在任何模型中使用 decimal 类型时,它都会被您的自定义 Binder 解析。

关于c# - 在 asp.net core mvc 中,小数的模型绑定(bind)不接受千位分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54169287/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com