网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

dotnet CultureInfo遇到欧洲如俄文小数点是逗号想转

时间:2025-01-22 17:07

人气:

作者:admin

标签:

导读:如题,当CultureInfo是俄文(ru-RU)时,浮点数中的点是用逗号表达的,如1.1会显示成1,1,造成很多的麻烦,当然如果全系统中全部采纳逗号作为浮点也没问题,只要用户接受就可以,但有...

如题,当CultureInfo是俄文(ru-RU)时,浮点数中的点是用逗号表达的,如1.1会显示成1,1,造成很多的麻烦,当然如果全系统中全部采纳逗号作为浮点也没问题,只要用户接受就可以,但有时需要继续用点号,那么解决办法如下。

我们知道CultureInfo.CurrentCulture静态变量是跟踪线程的,每个现场都有独立的CultureInfo.CurrentCulture值,它会决定当前线程的文化区域,包括时间、数字等的显示格式,这一步处理就会解决大部分浮点是逗号的问题。

var cultureInfo = new CultureInfo("ru-RU");
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.ReadOnly(cultureInfo);
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.ReadOnly(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;
    }
...
}

作者:Rick Carter
出处:http://pains.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信