【发布时间】:2021-03-11 16:26:56
【问题描述】:
我们有一个网络应用程序,它显示来自几个不同网络应用程序的数据。在每个网络应用程序中,文化是可配置的(由公司管理员在应用程序级别为所有用户设置,而不是每个用户)。
在我们的网络应用程序中,我们需要以为该应用程序配置的文化显示来自其他每个网络应用程序的数据。唯一的好消息是,目前我们不会在一个视图中显示来自两个应用程序的“混合”数据。通常,控制器及其所有操作只能处理来自单个应用程序的数据(这意味着来自该控制器的所有操作都将使用相同的文化)。
有几件事情我正在努力解决:
-
.NET Core 真的不像过去那样尊重设置文化吗?我已经尝试过了,但它不起作用(除非我将它设置在管道中的错误位置)。
Thread.CurrentThread.CurrentCulture = firstWebAppCultureInfo; Thread.CurrentThread.CurrentUICulture = firstWebAppCultureInfo;
真的只检查这些来查找和设置文化吗?
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
我知道我可以编写一个自定义提供程序,但这似乎对我没有帮助。我们已经从数据库中获取了应用程序的各种文化设置并将它们存储在会话中。
- 我的第一个想法是在用户每次点击控制器时写出一个文化 Cookie。我会从会话中读取文化并编写 cookie。但我发现这有几个问题。
问题 1: 如果我在控制器操作中写出 cookie,它不会在第一次从一种文化更改为另一种文化时“生效”。显然,cookie 已经被读取,并且已经为该请求设置了文化。我已经太晚了,无法做到这一点。
我尝试在控制器的构造函数(或基本控制器的构造函数)中写出 cookie,但此时尚未设置 HttpContext(它为空)。
我已经对过滤器进行了一些研究,我将编写一个操作过滤器来写入 cookie 以查看它是否有效,但请参阅问题 2。
问题 2:如果用户打开其浏览器的多个实例,则会出现另一个问题。我怀疑最后一种文化会“获胜”。因此,如果用户在一个浏览器中以 Culture fr-FR 显示数据,在另一个浏览器实例中显示 en-US 数据,并导航到写入该 en-US cookie 的控制器/视图,然后从另一个浏览器实例导航到应该使用 fr-FR 文化的页面,用户会从 cookie 中获取 en-US 设置,这是不可接受的。
- 我真的不想使用 QueryStringRequestCultureProvider,因为在 url 中显示它很难看。
我绝对不是这方面的专家。
我错过了什么? 你们将如何实现这一点?
提前致谢。
更新
我创建了一个 ActionFilter 和 TypeFilterAttribute,允许我将参数传递到 ActionFilter。使用该参数,我可以决定从 Session 中读取哪个键,以提供我为每个 Web 应用程序存储的文化设置。
从那里我可以用该属性和适当的参数标记每个控制器,以告诉操作过滤器使用什么文化(请记住,我们不混合数据,因此每个控制器显示的视图仅显示来自两个 Web 之一的数据应用程序,而不是两者)。
在 ActionFilter 中,我可以从 session 中查找文化字符串并执行以下操作,它可以工作:
var ci = new CultureInfo(this.cultureSetting);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
虽然这很令人鼓舞,但感觉很老套。所以请评论解决方案...
我想找到一种方法在 BaseController 或其他地方完成所有这些操作,因此我不需要在我们所有的控制器上放置属性。
但无论我在基本控制器中尝试过什么,似乎都是: a) 在管道中为该请求设置文化为时已晚,或 b) 在管道中过早访问 httpcontext。
想法?想法?
更新 2
我猜想在我的基本控制器中覆盖 OnActionExecuting 可以让我做与 ActionFilter 相同的事情...
所以我想我有一个解决方案,但如果有人有更好的想法,我正在倾听。
【问题讨论】: