ToB企服应用市场:ToB评测及商务社交产业平台
标题:
dotnet CultureInfo遇到欧洲如俄文小数点是逗号想转点的解决办法
[打印本页]
作者:
缠丝猫
时间:
2025-1-22 20:02
标题:
dotnet CultureInfo遇到欧洲如俄文小数点是逗号想转点的解决办法
如题,当CultureInfo是俄文(ru-RU)时,浮点数中的点是用逗号表达的,如1.1会显示成1,1,造成很多的麻烦,当然假如全系统中全部采纳逗号作为浮点也没问题,只要用户担当就可以,但有时须要继承用点号,那么解决办法如下。
1. 修改DefaultThreadCurrentCulture
我们知道CultureInfo.CurrentCulture静态变量是跟踪线程的,每个现场都有独立的CultureInfo.CurrentCulture值,它会决定当火线程的文化区域,包括时间、数字等的显示格式,这一步处理就会解决大部分浮点是逗号的问题。
var cultureInfo = new CultureInfo("ru-RU");
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.ReadOnly(cultureInfo);
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.ReadOnly(cultureInfo);
复制代码
2. aspnetcore中心件修改CultureInfo
这一步是今天想写这个文章的原因,由于找了很长时间才发现是这里导致的问题,虽然经过上面一步的修改,我们大部分业务代码不会再用逗号了,但是当我们在aspnetcore中启用了RequestLocalizationMiddleware,就会导致例如返回json时浮点数tostring或者拼接等还是逗号的问题。
修改的办法也很简单,启动时加如下代码就可以。
services.Configure<RequestLocalizationOptions>(options=>{
var cultures = options.SupportedCultures.Where(e => e.NumberFormat.NumberDecimalSeparator != ".").ToList();
foreach(var c in cultures)
{
c.NumberFormat.NumberDecimalSeparator = ".";
}
});
复制代码
原因是由于aspnetcore中的这个中心件代码导致的,为了说明问题简化了代码(代码来自微软官方github),注意Invoke和SetCurrentThreadCulture方法是关键问题所在。
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Localization;
/// <summary>
/// Enables automatic setting of the culture for <see cref="HttpRequest"/>s based on information
/// sent by the client in headers and logic provided by the application.
/// </summary>
public class RequestLocalizationMiddleware
{
private const int MaxCultureFallbackDepth = 5;
private readonly RequestDelegate _next;
private readonly RequestLocalizationOptions _options;
private readonly ILogger _logger;
/// <summary>
/// Creates a new <see cref="RequestLocalizationMiddleware"/>.
/// </summary>
/// <param name="next">The <see cref="RequestDelegate"/> representing the next middleware in the pipeline.</param>
/// <param name="options">The <see cref="RequestLocalizationOptions"/> representing the options for the
/// <see cref="RequestLocalizationMiddleware"/>.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> used for logging.</param>
public RequestLocalizationMiddleware(RequestDelegate next, IOptions<RequestLocalizationOptions> options, ILoggerFactory loggerFactory)
{
ArgumentNullException.ThrowIfNull(options);
_next = next ?? throw new ArgumentNullException(nameof(next));
_logger = loggerFactory?.CreateLogger<RequestLocalizationMiddleware>() ?? throw new ArgumentNullException(nameof(loggerFactory));
_options = options.Value;
}
/// <summary>
/// Invokes the logic of the middleware.
/// </summary>
/// <param name="context">The <see cref="HttpContext"/>.</param>
/// <returns>A <see cref="Task"/> that completes when the middleware has completed processing.</returns>
public async Task Invoke(HttpContext context)
{
ArgumentNullException.ThrowIfNull(context);
var requestCulture = _options.DefaultRequestCulture;
...
if (_options.RequestCultureProviders != null)
{
foreach (var provider in _options.RequestCultureProviders)
{
...
CultureInfo? cultureInfo = null;
CultureInfo? uiCultureInfo = null;
if (_options.SupportedCultures != null)
{
cultureInfo = GetCultureInfo(
cultures,
_options.SupportedCultures,
_options.FallBackToParentCultures);
if (cultureInfo == null)
{
_logger.UnsupportedCultures(provider.GetType().Name, cultures);
}
}
...
cultureInfo ??= _options.DefaultRequestCulture.Culture;
uiCultureInfo ??= _options.DefaultRequestCulture.UICulture;
var result = new RequestCulture(cultureInfo, uiCultureInfo);
requestCulture = result;
winningProvider = provider;
break;
}
}
...
SetCurrentThreadCulture(requestCulture);
...
await _next(context);
}
private static void SetCurrentThreadCulture(RequestCulture requestCulture)
{
CultureInfo.CurrentCulture = requestCulture.Culture;
CultureInfo.CurrentUICulture = requestCulture.UICulture;
}
...
}
复制代码
完
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4