当区域性更改时,与区域性无关的代码的工作方式会有所不同



这是我的控制器(为了简单起见,我删除了完整的代码(

public IActionResult Settings(SettingsViewModel model, ICollection<IFormFile> file)
{
ApplicationUser user = db.Users.FirstOrDefault(u => u.NormalizedUserName == User.Identity.Name.ToUpper());
return View(model);
}

这是我的路由:

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{culture=fa-IR}/{controller=Names}/{action=GirlAndBoy}/{p1=A}/{p2=1}");
});

该视图在文化方面工作得很好,并翻译成所有三种语言('en-us','tr-tr','fa-ir'(。

但问题是,用户已登录并在"en-us"和"fa-ir"中代码正常工作,但在"tr-tr"中,由于以下代码,user为空:

ApplicationUser user = db.Users.FirstOrDefault(u => u.NormalizedUserName == User.Identity.Name.ToUpper());

请注意,即使区域性为"tr-tr",跟踪也表明User.Identity.Name.ToUpper()具有正确的值。

它与文化和字符串之间的关系以及不同文化之间的大写有关。此页面与此问题非常相关:https://learn.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#stringequals

对于几乎所有拉丁字母,包括美国英语,字符 "i"(\u0069(是字符"I"(\u0049(的小写版本。 此大小写规则很快成为某人编程的默认规则 在这样的文化中。但是,土耳其语("tr-TR"(字母表包括一个 "I 带点"字符"İ"(\u0130(,这是 "我"。土耳其语还包括一个小写的"i without a dot"字符, "ı"(\u0131(,大写为"I"。

在这种情况下,您可能希望使用 OrdinalIgnoreCase 使用规范化 + 字符串比较。这应该可以解决文化和资本化问题。

var normalizedUserName = User.Identity.Name.Normalize();
ApplicationUser user = db.Users.FirstOrDefault(u => String.Equals(u.NormalizedUserName, normalizedUserName, StringComparison.OrdinalIgnore​Case));

最新更新