ASP.Net Core 多货币应用程序

7

我正在将一个应用程序从ASP.NET MVC转换到.NET Core,其中我曾经处理不同发票的货币类型。

 Thread.CurrentThread.CurrentCulture = CustomCulture.GetCultureInfo(Invoice.Vendor.VendorCurrency);
CustomCulture.GetCultureInfo(string CountryCode)使用供应商的货币创建自定义文化并添加一些默认格式和当前货币类型。
我有一个模型,其中包含一个货币类型,在该模型中,我们将从数据库中提取供应商的国家代码,并将其用于设置当前视图的货币类型。
根据我的理解,对于ASP.Net Core,相同的方法不起作用,因为视图运行在不同的线程上。
本质上,货币类型将发生变化,例如$ 或R或€。
有任何关于如何处理这个问题的想法吗?

本地化将使网站默认为一种货币。无论位置如何,我需要使用多种货币。 - user2806570
请查看此帖子(https://stackoverflow.com/questions/42540599/thread-currentthread-currentuiculture-in-asp-net-core),希望能对您有所帮助。 - Yaroslav Bigus
不要使用CultureInfo来猜测货币类型,因为这就是你将要做的事情。发票货币不会改变,即使目录价格进行本地化。请明确指定货币类型。如果你从亚马逊英国购买,货币可能与你的文化匹配(基于你的首选浏览器语言),但发票将以公司的货币计价。 - Panagiotis Kanavos
1
不要担心多币种价格。当您预订机票时,您看到的价格往往不是发行航空公司使用的货币。同一张发票可能在不同的货币中有不同的金额。为避免法律和会计问题,请使用Money类型,它结合了十进制金额货币,并防止您添加例如美元和欧元,或将美元乘以美元。在数据库中明确保存该货币与金额相邻。 - Panagiotis Kanavos
在任何情况下,您可能没有选择。会计规则可能会指定如何处理货币。每个发票行可能只有一种货币,或每张发票可能只有一种货币,或者您可能需要在同一行中保留多个货币金额(价值+货币)。唯一不能做的事情是从环境文化中猜测。 - Panagiotis Kanavos
多币种示例。 俄罗斯人通过欧洲旅行社购买印度航空公司的机票前往印度。 显示价格将以卢布显示,发票以欧元显示,而机票价格将以卢比显示。 不用担心信用卡支付,可以使用这三种货币中的任何一种。 - Panagiotis Kanavos
2个回答

3

在多文化环境下处理货币有点棘手。评论中有一些有价值的建议,我建议你阅读一下。

据我所知,这对ASP.Net Core不适用,因为视图运行在不同的线程上。

你只能使用以下方式来设置当前线程的区域性:

Thread.CurrentThread.CurrentCulture = CustomCulture.GetCultureInfo(Invoice.Vendor.VendorCurrency);

在您的应用程序中创建新线程时,您需要再次设置此内容。

相反,您可以在应用程序启动时使用DefaultThreadCurrentCultureDefaultThreadCurrentUICulture来默认为任何线程设置文化,如下:

CultureInfo.DefaultThreadCurrentCulture = CustomCulture.GetCultureInfo(Invoice.Vendor.VendorCurrency);
CultureInfo.DefaultThreadCurrentUICulture = CustomCulture.GetCultureInfo(Invoice.Vendor.VendorCurrency);

我通常在应用程序启动时使用以下代码来处理区域设置:

CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture("MyCultureValue");
//Setup things here for `cultureInfo` like currency in your case....

Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

Type type = typeof(CultureInfo);
type.InvokeMember("s_userDefaultCulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    cultureInfo,
                    new object[] { cultureInfo });

type.InvokeMember("s_userDefaultUICulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    cultureInfo,
                    new object[] { cultureInfo });

这些属性在.NET Framework 4.5及以上版本和.NET Core 1.0及以上版本中可用
在.NET Framework 4及之前的版本中,所有线程的区域性默认设置为Windows系统区域性。对于当前区域性与默认系统区域性不同的应用程序,此行为通常是不希望的。在.NET Framework 4.5中,DefaultThreadCurrentCulture属性使应用程序能够定义应用程序域中所有线程的默认区域性。
如果您尚未明确设置正在应用程序域中执行的任何现有线程的区域性,则设置DefaultThreadCurrentCulture属性也会更改这些线程的区域性。但是,如果这些线程在另一个应用程序域中执行,则它们的区域性由该应用程序域中的DefaultThreadCurrentCulture属性定义,或者如果没有定义默认值,则由默认系统区域性定义。因此,我们建议您始终明确设置主应用程序线程的区域性,并且不依赖于DefaultThreadCurrentCulture属性来定义主应用程序线程的区域性。
除非显式设置,否则DefaultThreadCurrentCulture属性的值为空,并且未分配显式区域性的应用程序域中的线程的区域性由默认的Windows系统区域性定义。

2

如果您已经具备所需的IT文化,就像您已经拥有的那样,那么您可以像这样使用string.Format

最初的回答:

如果你已经熟悉了所需的IT技术文化,那么你可以直接使用string.Format函数,像这样:

string.Format(Invoice.Vendor.VendorCurrency, "{0:C}", amount);

这也将允许您在不同的地方指定不同的文化,这在某些情况下可能是有优势的。

最初的回答:


有没有一种方法可以将其注入模型中,以最小化在每个视图上重新编码的工作量? - user2806570

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接