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

时间:2017-09-29 06:01:31

标签: asp.net-core asp.net-core-mvc

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

例如,有一个控制器

public class MainController : Controller
{
    private int a;

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

        return View(a)
    }
}

如果我第一次进入索引页面,我设置了= 10.然后我再次进入索引页面(例如刷新索引页面或索引页面中的分页,即移动到同一页面)实际上,我进入索引首次访问后,网址为:~Index?set=False

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

所以,我想使用不使用session的全局变量变量。

有什么办法吗?

1 个答案:

答案 0 :(得分:2)

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

每位用户

如果您希望存储一个仍然存在但仅对当前用户可见的变量,请使用session state

public int? A
{
    get 
    {
        return HttpContext.Current.Session["A"] as int?;
    }
    set
    {
        HttpContext.Current.Session["A"] = value;
    }
}

请注意,我们使用int?而不是int来处理尚未设置会话变量的情况。如果您希望默认为0,则只需使用the coalesce operator, ??

真正的全球

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

所以要么

static volatile public int a;

或者

public int? A
{
    get 
    {
        return HttpContext.Current.Application["A"] as int?;
    }
    set
    {
        HttpContext.Current.Application["A"] = value;
    }
}

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

您不必担心会话变量的线程同步;框架为你处理它。

注意:以上只是帮助您找到合适API的示例。它不一定能证明最好的模式 - 通过静态方法Current访问HttpContext被认为是不好的形式,因为它无法模拟上下文。请参阅this article了解如何通过DI将其公开给您的代码。