我正在使用这个例子,我发现如何通过它们加载类文件和访问变量。这是在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变量,因为如果多个函数同时访问该变量,则可以覆盖该变量。是否可以采用另一种方式,将变量发送到类文件?
答案 0 :(得分:12)
听起来您需要快速了解一些基本的ASP.Net Webforms概念。首先,我会反击一个常见的新手误解:
我认为许多新的ASP.Net开发人员都有这样的想法:Web服务器为每个访问其站点的用户会话保留其页面类的单个实例,并且每个回发或事件使用相同的页面类实例。这不是它的工作原理。 ASP.Net页面类实例几乎总是在一秒钟之内再次创建并销毁,而且大多数经验丰富的开发人员认为如果需要更长时间,它将成为一个大问题。
这里要记住的是ASP.Net仍然依赖于HTTP协议,而http归结为请求和响应。当您查看网页时,您的浏览器首先会向服务器发送请求。服务器响应,通常使用html文档。然后浏览器将解析html;根据它在html中看到的内容,浏览器可以向服务器发送更多请求以获取其他资源,例如javascript,图像或css文件。每个请求都会产生一个单独的响应,浏览器会使用所有这些资源将页面呈现给屏幕。但是,ASP.Net运行时通常不必处理额外的请求(这会使事情变慢) - 初始html需要ASP.Net支持;您希望其他资源成为可以缓存的基本文件。
当ASP.net运行时处理页面请求时,它将创建页面类的新实例。运行时将遵循ASP.Net Page lifecycle(这实际上应该命名为“ASP.Net Page Request Lifecycle”),并调用某些方法或在此类实例中引发某些特定事件。生命周期定义的订单。
这意味着每个回发或事件都会在您班级的其他实例中运行。
这也意味着每个回发或事件都在重建并传输进入您网页的html 所有,而不仅仅是您想要更改的部分。对于您的服务器代码,结果是类级变量在ASP.Net中唯一真正有用的东西是将在单个http请求中使用的东西。对于浏览器,结果是您在每次活动后都使用全新的DOM 。
要理解所有这些,在这里重要的是要很好地理解类和类实例之间的区别。你问题中的几个项目让我不确定你是否有这种理解。
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这样的东西。