C# 如何从 ASP.NET 中的任何类访问会话变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/621549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 10:38:50  来源:igfitidea点击:

How to access session variables from any class in ASP.NET?

c#asp.netsession-variables

提问by Prashant

I have created a class file in the App_Code folder in my application. I have a session variable

我在应用程序的 App_Code 文件夹中创建了一个类文件。我有一个会话变量

Session["loginId"]

I want to access this session variables in my class, but when I am writing the following line then it gives error

我想在我的班级中访问这个会话变量,但是当我写下一行时,它给出了错误

Session["loginId"]

Can anyone tell me how to access session variables within a class which is created in app_code folder in ASP.NET 2.0 (C#)

谁能告诉我如何访问在 ASP.NET 2.0 (C#) 的 app_code 文件夹中创建的类中的会话变量

采纳答案by M4N

(Updated for completeness)
You can access session variables from any page or control using Session["loginId"]and from any class (e.g. from inside a class library), using System.Web.HttpContext.Current.Session["loginId"].

(为完整性而更新)
您可以使用Session["loginId"]和从任何类(例如从类库内部)从任何页面或控件访问会话变量,使用System.Web.HttpContext.Current.Session["loginId"].

But please read on for my original answer...

但是请继续阅读我的原始答案...



I always use a wrapper class around the ASP.NET session to simplify access to session variables:

我总是在 ASP.NET 会话周围使用包装类来简化对会话变量的访问:

public class MySession
{
    // private constructor
    private MySession()
    {
      Property1 = "default value";
    }

    // Gets the current session.
    public static MySession Current
    {
      get
      {
        MySession session =
          (MySession)HttpContext.Current.Session["__MySession__"];
        if (session == null)
        {
          session = new MySession();
          HttpContext.Current.Session["__MySession__"] = session;
        }
        return session;
      }
    }

    // **** add your session properties here, e.g like this:
    public string Property1 { get; set; }
    public DateTime MyDate { get; set; }
    public int LoginId { get; set; }
}

This class stores one instance of itself in the ASP.NET session and allows you to access your session properties in a type-safe way from any class, e.g like this:

此类在 ASP.NET 会话中存储自身的一个实例,并允许您从任何类以类型安全的方式访问会话属性,例如:

int loginId = MySession.Current.LoginId;

string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;

DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

This approach has several advantages:

这种方法有几个优点:

  • it saves you from a lot of type-casting
  • you don't have to use hard-coded session keys throughout your application (e.g. Session["loginId"]
  • you can document your session items by adding XML doc comments on the properties of MySession
  • you can initialize your session variables with default values (e.g. assuring they are not null)
  • 它使您免于大量的类型转换
  • 您不必在整个应用程序中使用硬编码的会话密钥(例如 Session["loginId"]
  • 您可以通过在 MySession 的属性上添加 XML 文档注释来记录您的会话项目
  • 您可以使用默认值初始化会话变量(例如确保它们不为空)

回答by AnthonyWJones

Access the Session via the threads HttpContext:-

通过线程 HttpContext 访问会话:-

HttpContext.Current.Session["loginId"]

回答by Cerebrus

The answers presented before mine provide apt solutions to the problem, however, I feel that it is important to understand why this error results:

我之前提出的答案为问题提供了恰当的解决方案,但是,我认为了解为什么会导致此错误很重要:

The Sessionproperty of the Pagereturns an instance of type HttpSessionStaterelative to that particular request. Page.Sessionis actually equivalent to calling Page.Context.Session.

Session属性Page返回HttpSessionState与该特定请求相关的类型实例。Page.Session实际上相当于调用Page.Context.Session.

MSDNexplains how this is possible:

MSDN解释了这是如何实现的:

Because ASP.NET pages contain a default reference to the System.Web namespace (which contains the HttpContextclass), you can reference the members of HttpContexton an .aspx page without the fully qualified class reference to HttpContext.

由于 ASP.NET 页包含对 System.Web 命名空间(其中包含HttpContext类)的默认引用,因此您可以引用HttpContext.aspx 页上的成员,而无需对HttpContext.

However, When you try to access this property within a class in App_Code, the property will not be available to you unless your class derives from the Page Class.

但是,当您尝试在 App_Code 中的类中访问此属性时,除非您的类派生自 Page 类,否则您将无法使用该属性。

My solution to this oft-encountered scenario is that I never pass page objects to classes. I would rather extract the required objects from the page Session and pass them to the Class in the form of a name-value collection / Array / List, depending on the case.

我对这种经常遇到的情况的解决方案是,我从不将页面对象传递给 classes。我宁愿从页面会话中提取所需的对象,并根据情况以名称-值集合/数组/列表的形式将它们传递给类。

回答by Ernie

The problem with the solution suggested is that it can break some performance features built into the SessionState if you are using an out-of-process session storage. (either "State Server Mode" or "SQL Server Mode"). In oop modes the session data needs to be serialized at the end of the page request and deserialized at the beginning of the page request, which can be costly. To improve the performance the SessionState attempts to only deserialize what is needed by only deserialize variable when it is accessed the first time, and it only re-serializes and replaces variable which were changed. If you have alot of session variable and shove them all into one class essentially everything in your session will be deserialized on every page request that uses session and everything will need to be serialized again even if only 1 property changed becuase the class changed. Just something to consider if your using alot of session and an oop mode.

所建议的解决方案的问题在于,如果您使用的是进程外会话存储,它可能会破坏 SessionState 中内置的一些性能特性。(“状态服务器模式”或“SQL Server 模式”)。在 oop 模式中,会话数据需要在页面请求结束时进行序列化,并在页面请求开始时进行反序列化,这可能代价高昂。为了提高性能,SessionState 尝试仅反序列化第一次访问时仅反序列化变量所需的内容,并且仅重新序列化和替换更改的变量。如果您有很多会话变量并将它们全部放入一个类中,则会话中的所有内容基本上都将在使用会话的每个页面请求上反序列化,并且即使由于类更改而只更改了 1 个属性,也需要再次序列化所有内容。如果您使用大量会话和 oop 模式,请考虑一下。

回答by MunsterMan

I had the same error, because I was trying to manipulate session variables inside a custom Session class.

我遇到了同样的错误,因为我试图在自定义 Session 类中操作会话变量。

I had to pass the current context (system.web.httpcontext.current) into the class, and then everything worked out fine.

我必须将当前上下文 (system.web.httpcontext.current) 传递到类中,然后一切正常。

MA

回答by Captain America

This should be more efficient both for the application and also for the developer.

这对于应用程序和开发人员来说都应该更有效。

Add the following class to your web project:

将以下类添加到您的 Web 项目中:

/// <summary>
/// This holds all of the session variables for the site.
/// </summary>
public class SessionCentralized
{
protected internal static void Save<T>(string sessionName, T value)
{
    HttpContext.Current.Session[sessionName] = value;
}

protected internal static T Get<T>(string sessionName)
{
    return (T)HttpContext.Current.Session[sessionName];
}

public static int? WhatEverSessionVariableYouWantToHold
{
    get
    {
        return Get<int?>(nameof(WhatEverSessionVariableYouWantToHold));
    }
    set
    {
        Save(nameof(WhatEverSessionVariableYouWantToHold), value);
    }
}

}

Here is the implementation:

这是实现:

SessionCentralized.WhatEverSessionVariableYouWantToHold = id;

回答by Matty

In asp.net core this works differerently:

在 asp.net core 中,这以不同的方式工作:

public class SomeOtherClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private ISession _session => _httpContextAccessor.HttpContext.Session;

    public SomeOtherClass(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void TestSet()
    {
        _session.SetString("Test", "Ben Rules!");
    }

    public void TestGet()
    {
        var message = _session.GetString("Test");
    }
}

Source: https://benjii.me/2016/07/using-sessions-and-httpcontext-in-aspnetcore-and-mvc-core/

来源:https: //benjii.me/2016/07/using-sessions-and-httpcontext-in-aspnetcore-and-mvc-core/