在没有会话的情况下访问asp.net中的公共类变量

时间:2012-02-15 18:18:19

标签: asp.net vb.net session

我正在使用这个例子,我发现如何通过它们加载类文件和访问变量。这是在App_Code文件夹中名为Class1.vb的文件中(这不是应用程序项目):

Imports Microsoft.VisualBasic
Public Class my_class
    Public Shared Sub my_sub()
        Dim vartest As String
        vartest = 10
        HttpContext.Current.Session("myvar") = vartest
    End Sub
End Class

这是aspx文件的代码隐藏:

    Imports my_class
Partial Public Class test
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        my_class.my_sub()
        Label1.Text = HttpContext.Current.Session("myvar")
    End Sub
End Class

如何在不使用会话的情况下访问vartest变量,因为如果多个函数同时访问该变量,则可以覆盖该变量。是否可以采用另一种方式,将变量发送到类文件?

4 个答案:

答案 0 :(得分:12)

听起来您需要快速了解一些基本的ASP.Net Webforms概念。首先,我会反击一个常见的新手误解:

您的Page类不会在Web服务器上停留很长时间

我认为许多新的ASP.Net开发人员都有这样的想法:Web服务器为每个访问其站点的用户会话保留其页面类的单个实例,并且每个回发或事件使用相同的页面类实例。这不是它的工作原理。 ASP.Net页面类实例几乎总是在一秒钟之内再次创建并销毁,而且大多数经验丰富的开发人员认为如果需要更长时间,它将成为一个大问题。

ASP.NET依赖于HTTP协议

这里要记住的是ASP.Net仍然依赖于HTTP协议,而http归结为请求响应。当您查看网页时,您的浏览器首先会向服务器发送请求。服务器响应,通常使用html文档。然后浏览器将解析html;根据它在html中看到的内容,浏览器可以向服务器发送更多请求以获取其他资源,例如javascript,图像或css文件。每个请求都会产生一个单独的响应,浏览器会使用所有这些资源将页面呈现给屏幕。但是,ASP.Net运行时通常不必处理额外的请求(这会使事情变慢) - 初始html需要ASP.Net支持;您希望其他资源成为可以缓存的基本文件。

ASP.Net运行时为每个请求创建一个新类实例。

当ASP.net运行时处理页面请求时,它将创建页面类的新实例。运行时将遵循ASP.Net Page lifecycle(这实际上应该命名为“ASP.Net Page Request Lifecycle”),并调用某些方法或在此类实例中引发某些特定事件。生命周期定义的订单。

这意味着每个回发或事件都会在您班级的其他实例中运行。

这也意味着每个回发或事件都在重建并传输进入您网页的html 所有,而不仅仅是您想要更改的部分。对于您的服务器代码,结果是类级变量在ASP.Net中唯一真正有用的东西是将在单个http请求中使用的东西。对于浏览器,结果是您在每次活动后都使用全新的DOM

要理解所有这些,在这里重要的是要很好地理解类和类实例之间的区别。你问题中的几个项目让我不确定你是否有这种理解。

ASP.Net运行时在您站点的所有用户之间共享一个应用程序实例

Web服务器通常只有一个应用程序实例用于整个网站及其所有用户。因此,具有共享/静态范围的任何内容对每个用户都是通用的。在ASP.Net中很少适用于任何共享/静态的东西。

那么,您如何处理应该与单个用户或访问您的网站的数据?

完全 Session的用途。在任何给定时间,会话始终对于单个请求是唯一的。您担心同时访问会话的多个功能,但这不会发生。 ASP.Net页面生命周期确保除非您手动生成其他线程,否则一次只有一个函数针对给定的HttpContext和Session运行。如果用户以几乎同时发送两个具有相同Session / HttpContext的请求,则ASP.Net运行时将保留一个请求,直到另一个完成。如果您不想一直引用会话,则可以在类中构建包含会话变量的属性。有关示例,请参阅@Pankaj's answer

答案 1 :(得分:2)

首先,Session具有用户范围,因此不会被其他请求覆盖。

Is it safe to access asp.net session variables through static properties of a static object?

您可以将访问权限封装到属性中:

Public Shared Property MyVar() As String
    Get
        If HttpContext.Current.Session("MyVar") Is Nothing Then
            HttpContext.Current.Session("MyVar") = ""
        End If
        Return DirectCast(HttpContext.Current.Session("MyVar"), String)
    End Get
    Set(value As String)
        HttpContext.Current.Session("MyVar") = value
    End Set
End Property

然后你可以通过以下方式得到变量:

Label1.Text = my_class.MyVar

答案 2 :(得分:2)

除了“ Tim Schmelter ”回复......

您可以创建一个将继承自

BaseClass
System.Web.UI.Page

按照“Tim”的建议放置物业。您需要做的唯一更改是将访问修饰符更改为Protected,您应该删除Public and Shared

您还可以保留其他常用功能,我们可以在其他类中重复使用的属性...同样,您也可以为用户控件创建BaseControls

最后,在Web表单中继承此类....

希望这会对你有帮助......

基类代码

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web

Public Class BaseClass
    Inherits System.Web.UI.Page
    Protected Property MyVar() As String
        Get
            If HttpContext.Current.Session("MyVar") Is Nothing Then
                HttpContext.Current.Session("MyVar") = ""
            End If
            Return Convert.ToString(HttpContext.Current.Session("MyVar"))
        End Get
        Set
            HttpContext.Current.Session("MyVar") = value
        End Set
    End Property
End Class

示例代码“在代码后面” - 显示受保护的成员数据从基类的使用

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Partial Class Default5
    Inherits BaseClass
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        If Not Page.IsPostBack Then
            Dim str As String = Me.MyVar
        End If
    End Sub
End Class

答案 3 :(得分:0)

通常你可以使用不同的地方来存储应用程序状态:应用程序(应用程序范围,将状态保存到应用程序域),Session(可以保存当前浏览器会话将要访问的所有内容),ViewState(存储在隐藏输入中的变量)字段,将发布在每个回发)。当然,您也可以将状态保存到数据库或文件。我不确定你想要实现什么,但看起来你正在寻找像ViewState这样的东西。

阅读ASP.NET State Management