ASP.NET EndPont不尊重使用一次性文化切换器的当前线程UI培养
我有一个奇怪的翻译问题,即在NetCore 3.1上运行的ASP.NET应用程序,在部署后约20分钟,资源字符串仅作为主要文化作为主要文化。
该项目使用.RESX文件以三种语言存储字符串(常规/通用/en,sv,en),这些语言存储在一个单独的项目中,以便将它们引用为例如lang.general.eneral.emailsubject
。除了这个终点以外,这是其他任何地方都可以使用的,但是它是唯一具有这种逻辑的终点。
有两个部署,一种是sv-se
,另一种为en-gb
。端点的呼叫者可以将“请求的文化”指定为其他东西,sv-gb
或en-se
。
99%的时间,这种要求的文化与主要文化相同。但是,有时指定的方式不同,然后翻译是错误的。虽然我可以在每次部署后复制此内容,但我不明白原因吗?
代码看起来像这样;
public sealed class TemporaryLanguageSwitcher : IDisposable
{
private readonly CultureInfo initialCulture;
private readonly CultureInfo initialUiCulture;
public TemporaryLanguageSwitcher(CultureInfo culture)
{
initialCulture = CultureInfo.CurrentCulture;
initialUiCulture = CultureInfo.CurrentUICulture;
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
void IDisposable.Dispose()
{
CultureInfo.CurrentCulture = initialCulture;
CultureInfo.CurrentUICulture = initialUiCulture;
}
}
public static class CultureInfoExtensions
{
public static TemporaryLanguageSwitcher AsThreadCulture(this CultureInfo culture)
{
return new TemporaryLanguageSwitcher(culture);
}
}
public class MailController : ControllerBase
{
public static IDisposable CultureSetter(CultureInfo newCulture) => newCulture.AsThreadCulture();
public static IDisposable CreateEmailRequestScope(EmailRequest request)
{
string culture = string.IsNullOrEmpty(request.requestedCulture) ? "sv-SE" : request.requestedCulture; //en-SE
return CultureSetter(CultureInfo.GetCultureInfo(culture));
}
[HttpPost]
public async Task<MailResponse> SendEmail([FromBody] EmailRequest request)
{
var requestCulture = request.requestedCulture; //en-SE
var emailSubject = Lang.General.EmailSubject; //This is always the default
using (CreateEmailRequestScope(request))
{
var emailSubject = Lang.General.EmailSubject; //This is wrong 10-20 mins after deployment - Should be Hello, But is Hej
request.emailSubject = emailSubject;
return await mailer.Send(request);
}
}
}
感谢您的建议!
I have a strange translation issue with an ASP.net application running on netcore 3.1, where around 20 minutes after deployment, a resource string only comes in the language set as the primary culture.
The project uses .resx files to store strings in three languages (general/generic/en, sv, en), which are stored in a separate project so that they can be referenced as, for example, Lang.General.EmailSubject
. This is working everywhere else, other than this endpoint, but it is the only one with this logic.
There are two deployments, one with primary culture as sv-SE
and one as en-GB
. The caller of the endpoint can specify the 'requestedCulture' as something else, either sv-GB
or en-SE
.
99% of the time, this requested culture is the same as the primary culture. However, sometimes it's specified differently, and then the translation is wrong. While I can replicate this after each deployment, I don't understand the cause?
The code looks like this;
public sealed class TemporaryLanguageSwitcher : IDisposable
{
private readonly CultureInfo initialCulture;
private readonly CultureInfo initialUiCulture;
public TemporaryLanguageSwitcher(CultureInfo culture)
{
initialCulture = CultureInfo.CurrentCulture;
initialUiCulture = CultureInfo.CurrentUICulture;
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
void IDisposable.Dispose()
{
CultureInfo.CurrentCulture = initialCulture;
CultureInfo.CurrentUICulture = initialUiCulture;
}
}
public static class CultureInfoExtensions
{
public static TemporaryLanguageSwitcher AsThreadCulture(this CultureInfo culture)
{
return new TemporaryLanguageSwitcher(culture);
}
}
public class MailController : ControllerBase
{
public static IDisposable CultureSetter(CultureInfo newCulture) => newCulture.AsThreadCulture();
public static IDisposable CreateEmailRequestScope(EmailRequest request)
{
string culture = string.IsNullOrEmpty(request.requestedCulture) ? "sv-SE" : request.requestedCulture; //en-SE
return CultureSetter(CultureInfo.GetCultureInfo(culture));
}
[HttpPost]
public async Task<MailResponse> SendEmail([FromBody] EmailRequest request)
{
var requestCulture = request.requestedCulture; //en-SE
var emailSubject = Lang.General.EmailSubject; //This is always the default
using (CreateEmailRequestScope(request))
{
var emailSubject = Lang.General.EmailSubject; //This is wrong 10-20 mins after deployment - Should be Hello, But is Hej
request.emailSubject = emailSubject;
return await mailer.Send(request);
}
}
}
Thanks for any suggestions!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最后,我在其他来源的帮助下找到了问题的原因。
我们正在使用RESX Resource Manager,它使我们的静态键入翻译覆盖了覆盖线程。覆盖线程。元素文化并始终返回相同的翻译。在这种情况下,这是一个名为
文化
的领域,设置了端点文化中的其他地方,然后翻译停止在此端点上工作。
希望这对别人有帮助!
In the end I found the cause of the issue with help from other sources.
We were using the ResX resource manager and it put an override in our static typed translations, which overrides Thread.CurrentUICulture and always return the same translation. In this case it's a field called
Culture
Somewhere else in the endpoint Culture was set and after that translation stopped working on this endpoint.
Hope this helps someone else!