在 ASP.NET Core 控制器中使用全局变量

wal*_*lah 4 asp.net-core-mvc asp.net-core

问题很简单,但我不知道如何使用它。

例如有一个控制器

public class MainController : Controller
{
    private int a;

    public IActionResult Index(bool set = true)
    {
        if (set) a = 10;

        return View(a)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我第一次进入索引页面,我设置 a = 10。然后我再次进入索引页面(例如刷新索引页面或在索引页面中分页,即在同一页面中移动)实际上,我进入带有 url 的索引页面:~Index?set=False第一次访问后。

然后a有 0(int 变量的默认值)。我不知道控制器页面(控制器类)在我生成时总是被初始化,即使我移动到同一页面。

所以,我想使用不使用会话的全局变量之类的变量。

有什么办法吗?

Joh*_* Wu 5

听起来您希望在请求之间保留一个变量。

每个用户

如果您希望存储一个持续存在但仅对当前用户可见的变量,请使用会话状态

public int? A
{
    get 
    {
        return HttpContext.Current.Session["A"] as int?;
    }
    set
    {
        HttpContext.Current.Session["A"] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们使用int?而不是int为了处理尚未设置会话变量的情况。如果您更喜欢默认为 0,则可以简单地使用合并运算符 ?? .

真正全球化

如果您希望以一种所有用户只有一个副本的方式持久化变量,您可以将其存储在静态变量或应用程序状态变量中。

所以要么

static volatile public int a;
Run Code Online (Sandbox Code Playgroud)

或者

public int? A
{
    get 
    {
        return HttpContext.Current.Application["A"] as int?;
    }
    set
    {
        HttpContext.Current.Application["A"] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,用户之间共享的变量可以随时更改(由于其他线程中的活动),因此您应该小心处理它们。对于int-size 或更小的变量,处理器将执行原子读取和写入,但对于大于 a 的变量,int您可能需要使用Interlockedlock来控制访问。

您无需担心会话变量的线程同步;框架会为您处理。

注意:以上只是帮助您找到正确 API 的示例。它不一定展示最佳模式——通过静态方法访问 HttpContextCurrent被认为是不好的形式,因为它无法模拟上下文。请参阅本文以了解通过 DI 将其公开给您的代码的方法。