You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中如何获取用户语言ID并设为全局变量按需调用

工具
  • Visual Studio 2022 社区版
  • .NET Core 7.0
  • Razor Pages
需求说明

为减少应用中数据库调用次数,我希望创建一个存储当前用户语言ID的全局变量,在用户登录时为其赋值。之后可在各页面模型中按需调用该变量,以此定义UI语言。我已为全局变量声明了一个类,但无法继续推进:既无法获取当前用户ID,也无法调用数据库表...

问题

如何正确实现这一功能?

代码示例
namespace MyApp.Models
{
    private readonly Models.ApplicationDbContext _context;

    public class Class
    {
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        private int langId = _context.Languages.where(x=>x.UserId = userId).FirstOrDefault().Id;
        public int GetLangId 
        {
            get { return langId; }
            set { langId = value; }
        }       
    }
}
解决方案

你的代码存在几个核心问题:直接在类字段中写业务逻辑、无法直接访问User对象、依赖注入位置错误、未处理空引用风险,而且静态类/全局变量会在多用户环境下冲突——每个用户的语言ID是独立的,不能共用同一存储。下面提供两种可行方案:

方案一:登录时将语言ID写入用户Claims(推荐)

这种方式最直接,登录后语言ID会随用户身份信息一起传递,无需额外查询数据库:

  1. 在登录逻辑中(比如Login.cshtml.cs的OnPostAsync方法),获取用户的语言ID并添加到Claims:
var user = await _userManager.FindByNameAsync(Input.Email);
if (user != null)
{
    // 从数据库获取用户语言ID,没有则设默认值1
    var language = await _context.Languages.FirstOrDefaultAsync(x => x.UserId == user.Id);
    var langId = language?.Id ?? 1;

    // 创建ClaimsIdentity并添加语言ID Claim
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, user.Id),
        new Claim("LangId", langId.ToString())
        // 其他必要Claims...
    };
    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));

    return RedirectToPage("/Index");
}
  1. 在任意页面模型或服务中获取语言ID:
// 页面模型中直接获取
var langId = int.Parse(User.FindFirstValue("LangId"));

// 服务中需注入IHttpContextAccessor来访问用户信息
public class MyService
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public MyService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public int GetCurrentLangId()
    {
        var langIdStr = _httpContextAccessor.HttpContext?.User.FindFirstValue("LangId");
        return int.TryParse(langIdStr, out int id) ? id : 1;
    }
}

方案二:使用Scoped服务存储语言ID

适合需要动态修改语言ID的场景,Scoped服务的生命周期与请求一致,每个用户请求会创建独立实例:

  1. 定义语言提供器接口和实现类:
public interface ILanguageProvider
{
    int LangId { get; set; }
}

public class LanguageProvider : ILanguageProvider
{
    public int LangId { get; set; }
}
  1. 在Program.cs中注册为Scoped服务:
builder.Services.AddScoped<ILanguageProvider>();
// 注册IHttpContextAccessor(如果服务中需要访问用户信息)
builder.Services.AddHttpContextAccessor();
  1. 登录时设置语言ID:
    在Login.cshtml.cs中注入ILanguageProvider和ApplicationDbContext:
private readonly ILanguageProvider _languageProvider;
private readonly ApplicationDbContext _context;

public LoginModel(ILanguageProvider languageProvider, ApplicationDbContext context)
{
    _languageProvider = languageProvider;
    _context = context;
}

public async Task<IActionResult> OnPostAsync()
{
    // 登录验证逻辑...
    var user = await _userManager.FindByNameAsync(Input.Email);
    if (user != null)
    {
        var language = await _context.Languages.FirstOrDefaultAsync(x => x.UserId == user.Id);
        _languageProvider.LangId = language?.Id ?? 1;
        // 完成登录逻辑...
        return RedirectToPage("/Index");
    }
    // 错误处理...
}
  1. 在其他页面模型中获取:
public class IndexModel : PageModel
{
    private readonly ILanguageProvider _languageProvider;
    public int CurrentLangId { get; set; }

    public IndexModel(ILanguageProvider languageProvider)
    {
        _languageProvider = languageProvider;
    }

    public void OnGet()
    {
        CurrentLangId = _languageProvider.LangId;
        // 用CurrentLangId设置UI语言...
    }
}

代码错误修正说明

你提供的代码需要调整以下几点才能运行:

  • 依赖注入的_context必须放在类的构造函数中,不能直接在类外声明
  • 获取User需要通过IHttpContextAccessor,不能直接在类字段中访问
  • 必须处理FirstOrDefault()返回null的情况,避免空引用异常
  • 不能用静态类存储用户专属数据,会导致多用户数据冲突

内容的提问来源于stack exchange,提问作者Fillo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:47:09