当前位置: 首页 > news >正文

电商购物网站毕节做网站

电商购物网站,毕节做网站,什么网站可以接单做设计,三国类网页游戏前十名背景在将公司一款基于 .NET Framework 的控制台程序迁移到 .NET Core 3.1 时#xff0c;发现程序中本地化的部分失效#xff0c;症状类似于对 Thread.CurrentThread.CurrentCulture.Name 的值进行 Substring() 操作时抛出 ArgumentOutOfRangeException 异常。该程序在 Window… 背景在将公司一款基于 .NET Framework 的控制台程序迁移到 .NET Core 3.1 时发现程序中本地化的部分失效症状类似于对 Thread.CurrentThread.CurrentCulture.Name 的值进行 Substring() 操作时抛出 ArgumentOutOfRangeException 异常。该程序在 Windows Container 中工作良好迁移为 .NET Core 后在我的 Windows 开发机上也运行良好一旦部署到 K8s 的 Linux 容器中就会出现问题。容器使用的是基于微软官方的 .NET Runtime 3.1 镜像https://hub.docker.com/_/microsoft-dotnet-runtime/。本文按我当时解决此问题的思路记录从 Windows 开始挨个环境测试 CurrentThread.CurrentCulture。TL;DR 先上结论.NET Core Runtime 的 Linux 镜像没有设置语言信息导致通过 CurrentThread.CurrentCulture 获取的 Name 为 String.Empty。只需要在生成镜像时为 Linux 设置语言即可本文末尾附有解决方案。在 Windows 中获取区域设置先创建一个名为 CultureTest 的控制台项目看看效果这里使用 .NET Core 的 LTS 版本 .NET Core 3.1 为例通过命令行执行dotnet new console -o CultureTest --framework netcoreapp3.1 然后进入 CultureTest 文件夹将生成的 Program.cs 替换为如下内容using System; using System.Globalization; using System.Linq; using System.Threading;namespace CultureTest {class Program{static void Main(){PrintProperty(Thread.CurrentThread.CurrentCulture);Thread.Sleep(TimeSpan.FromDays(1));}private static void PrintProperty(CultureInfo cultureInfo){var printableProperties cultureInfo.GetType().GetProperties().Where(p p.PropertyType.IsValueType || p.PropertyType typeof(string));foreach (var property in printableProperties){Console.WriteLine(${property.Name}: {property.GetValue(cultureInfo)});}}} } PrintProperty() 方法主要用途是将 CultureInfo 类中所有值类型和 string 类型的属性找到并将我们传入的 Thread.CurrentThread.CurrentCulture 对象的这些属性值都打印出来。Thread.Sleep() 是为在后面测试 docker 时用于防止程序运行后直接退出之用。我在一台区域设置为 中文(简体中国) 的 Windows 10 PC 上运行上述代码dotnet run 可以看见 Name 为 zh-CN 和 Windows 一致。查看信息后由于有 Thread.Sleep() 的逻辑需要通过 Ctrl C 来停止程序的运行后面 Linux 和 Docker 中也一样。在 Linux 中获取区域信息我在 WSLhttps://docs.microsoft.com/windows/wsl/install-win10 中安装了 Debian 10并安装了 .NET Core 3.1 SDK下面用 Debian 来进行测试。locale 命令在 Linux 中可以使用 locale 命令查看当前语言环境信息locale 关注 LANG 的值现在显示为 en_US.UTF-8。locale 命令加上 -a 选项后可以查看可用的语言环境信息locale -a 可以看到这个 Debian 除了当前的 en_US.UTF-8还支持其它几种语言环境。通过 CurrentThread 获取由于是 WSL可以通过 /mnt 中挂载的 Windows 文件系统直接导航到上一节创建的项目中并运行cd /mnt/d/projects/CultureTest dotnet run 可以看见 Name 为 en-US 和 locale 命令得到的一致。在 Docker 容器中获取区域信息下面将测试程序放入容器中运行。发布测试程序先发布 CultureTest 项目dotnet publish -c Release 默认会发布到 .\bin\Release\netcoreapp3.1\publish\ 文件夹下可以使用 dirWindows 或 lsLinux 命令查看发布结果。创建 Dockerfile接下来为 CultureTest 生成镜像。首先在 CultureInfo 项目根目录.csproj 所在的目录下创建 Dockerfile 并填入以下内容FROM mcr.microsoft.com/dotnet/runtime:3.1COPY ./bin/Release/netcoreapp3.1/publish/ /app/ WORKDIR /app ENTRYPOINT [dotnet, CultureTest.dll] 这里使用 .NET Core 官方提供的 .NET Runtime 镜像 mcr.microsoft.com/dotnet/runtime:3.1 作为 Runtime拷贝刚刚发布到 .\bin\Release\netcoreapp3.1\publish\ 的程序到容器的 /app 文件夹下将容器的工作目录设为 /app 文件夹通过 dotnet CultureTest.dll 命令运行测试项目生成镜像在 Dockerfile 所在的目录下执行 docker build 命令生成镜像docker build -t culture-test . -t culture-test 设置镜像的名称为 culture-test不要漏掉最后的 .运行并查看结果通过上一步创建的 culture-test 镜像生成一个容器并查看执行结果docker run culture-test 发现 Name 后没有任何内容。经过测试CurrentThread.CurrentCulture 不会为 null并且 Name 属性的值为 String.Empty 而非 null。这也是我遇到问题的原因对 String.Empty 进行了 Substring() 操作所以抛出了 ArgumentOutOfRangeException 异常问题重现。在容器中执行 locale进入容器查看 Linux 的语言环境信息docker run -d culture-test docker exec -it [your_container_id] /bin/bash 通过 -d 让程序后台运行有 Thread.Sleep() 在所以程序不会退出这样我们就能进入到容器内执行命令这一步执行后会返回容器 id通过 exec 执行容器里的 /bin/bash发现 locale 命令返回的 LANG 也是空白的。并且 locale -a 命令返回的 C 和 POSIX 都是默认不含语言的环境。原因如果使用过 Linux 的 GUI 安装 Linux一般会让选择语言和地区但 mcr.microsoft.com/dotnet/runtime:3.1 以及它基于的 Debian 镜像https://github.com/dotnet/dotnet-docker/blob/87cbc30052e5dc892313122e26364b5051df905b/src/runtime-deps/3.1/buster-slim/amd64/Dockerfile都没有设置语言所以导致我们通过 locale 或是 C# 的 CurrentThread.CurrentCulture 获取到的都是空白的内容。那么结合上面的信息要想让依赖于区域语言信息的程序不报错有两种方案修改程序增加对 CurrentCulture.Name 的判断如果 CurrentCulture.Name String.Empty则为程序设置一个默认 Culture修改运行环境将默认语言信息设置为需要的值例如 en-US为容器中的 Linux 设置语言信息虽然最后我选择的是修改程序但也来了解一下这种情况如何为容器中的 Linux 设置语言信息。通过搜索找到了 StackOverflow 上的提问How to set the locale inside a Debian/Ubuntu Docker container?https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container并从中得到了解决方案。方案一通过安装 locales-all 包通过安装 locales 和 locales-all 包可以把所有支持的语言信息都安装到系统中再通过环境变量设置需要的语言。修改 DockerfileFROM mcr.microsoft.com/dotnet/runtime:3.1# 安装所有支持的语言信息并设置 en_US.UTF-8 为当前语言 RUN apt-get update RUN apt-get install -y locales locales-all ENV LANG en_US.UTF-8COPY ./bin/Release/netcoreapp3.1/publish/ /app/ WORKDIR /app ENTRYPOINT [dotnet, CultureTest.dll] 方案二通过安装 locales 包并修改 locale.gen 文件修改 DockerfileFROM mcr.microsoft.com/dotnet/runtime:3.1# 安装 locales 包并修改 locale.gen 文件再设置语言 RUN apt-get update RUN apt-get install -y locales RUN sed -i -e /en_US.UTF-8/s/^# //g /etc/locale.gen locale-gen ENV LANG en_US.UTF-8 COPY ./bin/Release/netcoreapp3.1/publish/ /app/ WORKDIR /app ENTRYPOINT [dotnet, CultureTest.dll] 安装 locales 后会生成 /etc/locale.gen 文件文件内容类似于# en_SG ISO-8859-1 # en_SG.UTF-8 UTF-8 # en_US ISO-8859-1 # en_US.ISO-8859-15 ISO-8859-15 # en_US.UTF-8 UTF-8 # en_ZA ISO-8859-1 # en_ZA.UTF-8 UTF-8 # en_ZM UTF-8 # en_ZW ISO-8859-1 # en_ZW.UTF-8 UTF-8 通过 sed 命令/en_US.UTF-8将包含 en_US.UTF-8 字样的行/s执行替换/^#将行首的 #/替换为空白然后执行 locale-gen 命令并设置 LANG 的值为 en_US.UTF-8。这两种方式都能确保 CurrentThread.CurrentCulture 获取到正确的 Culture Name。
http://www.yutouwan.com/news/272074/

相关文章:

  • 网盘做网站服务器黄石网站设计公司
  • 河北众成建设有限公司网站做网站需要什么系统
  • 网站后台显示连接已重置wordpress跳转
  • 廊坊网站建站网站公司建网站有免费的吗
  • 企业网站必须做可信网站认证新工商名录企业应用平台
  • 模板网站 优帮云专做西餐的网站
  • 网站技术的解决方案如何做淘客网站
  • 个人网站备案都需要什么网站如何添加认证联盟
  • 怎样增加网站流量wordpress 如果存在则
  • 网站建设哪些字体没有版权平台的重要性
  • 最新网站源码下载做网站公司怎么备案客户网站
  • 苏州的建筑公司网站网站建设有哪些文件
  • wordpress 淘宝客网站模板官方网站建立
  • 企业网站源码带后台管理辽宁省建设厅网站更新
  • 机房建设 网站找工程项目信息哪个app好用
  • 织梦网站专题模板装饰公司设计用什么软件
  • 郑州企业建网站制作做的网站
  • 网站的备案all网络营销第二板斧是什么
  • 济源网站建设佛山网站建设报价
  • 手机app制作流程宁波seo推广如何收费
  • 制作销售网站查看网站被恶意镜像
  • 有没有网站建设的教程承德做网站
  • 高端网站建设多少钱湖北省建设厅网站上岗证查询
  • 个人网站做什么类型好重庆建网站cqiezscom
  • 公司网站及微信公众号建设意义好用的外贸网站
  • 网站开发公司盈利wordpress下载链接
  • 网站的网络营销方案建网站浩森宇特
  • 门户网站建设与管理商务网站建设实训报告1600字
  • 桂林市区面积德阳网站怎么做seo
  • 企业网站页面图片三河网站建设-七天网络