Доступ к переменным открытого класса в asp.net без сеанса - PullRequest
3 голосов
/ 15 февраля 2012

Я использую этот пример, который я нашел, чтобы узнать, как загружать файлы классов и обращаться к переменным через них. Это в файле Class1.vb в папке App_Code (это не проект приложения):

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 ]

12 голосов
/ 16 февраля 2012

Похоже, вам нужен краткий обзор некоторых основных концепций ASP.Net Webforms. Сначала я опровергну распространенное заблуждение новичка:

Ваш класс Page не торчит на веб-сервере очень долго

Я думаю, что многие новые разработчики ASP.Net считают, что веб-сервер должен хранить один экземпляр своего класса страниц для каждого сеанса пользователя, который посещает их сайт, и каждый постбэк или событие использует этот же экземпляр класса страницы. Это просто не так, как это работает. Экземпляры классов страниц ASP.Net почти всегда создаются и снова уничтожаются , причем менее чем за секунду, и большинство опытных разработчиков видят в этом большую проблему, если это занимает больше времени.

ASP.NET использует протокол HTTP

Здесь следует помнить, что ASP.Net по-прежнему использует протокол HTTP, и http сводится к запросам и ответам . Когда вы просматриваете веб-страницу, ваш браузер сначала отправляет запрос на сервер. Сервер отвечает , обычно HTML-документом. Браузер будет анализировать HTML; в зависимости от того, что он видит в html, браузер может отправлять на сервер больше запросов на дополнительные ресурсы, такие как файлы javascript, images или css. Каждый запрос приводит к отдельному ответу, и браузер использует все эти ресурсы для отображения страницы на экране. Однако среда выполнения ASP.Net обычно не должна обрабатывать дополнительные запросы (это может замедлить работу) & mdash; только первоначальный html нуждается в поддержке ASP.Net; вы хотите, чтобы другие ресурсы были основными файлами, которые можно кэшировать.

Среда выполнения ASP.Net создает новый экземпляр вашего класса для каждого запроса.

Когда среда выполнения ASP.net обрабатывает запрос на страницу, она создает новый экземпляр класса вашей страницы. Среда выполнения будет следовать жизненному циклу ASP.Net Page (это действительно должно называться «ASP.Net Page Request Lifecycle») и вызывать определенные методы или вызывать определенные события в этом классе. Например, в определенном порядке, определенном жизненным циклом.

Это означает, что каждый постбэк или событие выполняется в другом экземпляре вашего класса.

Это также означает, что каждый постбэк или событие перестраивает и передает все html-страниц, которые попадают на вашу страницу, а не только те части, которые вы хотите изменить. Для вашего серверного кода следствием является то, что переменные уровня класса действительно полезны в ASP.Net - это вещи, которые будут использоваться в одном HTTP-запросе. Для браузера это означает, что вы работаете с новым DOM после каждого события .

Чтобы понять все это, здесь важно также хорошо понимать разницу между классом и экземпляром класса. Несколько вопросов в вашем вопросе заставляют меня сомневаться, есть ли у вас такое понимание.

Среда выполнения ASP.Net разделяет один экземпляр приложения среди всех пользователей вашего сайта

У веб-сервера обычно есть только один экземпляр вашего приложения для всего веб-сайта и всех его пользователей. Следовательно, все с общей / статической областью видимости является общим для каждого пользователя. В ASP.Net редко бывает уместно, чтобы что-то было общим / статическим.

Итак, как вы обрабатываете данные, которые должны храниться у одного пользователя или при посещении вашего сайта?

Это точно , для чего Session. Сессия всегда будет уникальной для отдельного запроса в любой момент времени. Вы беспокоитесь о одновременном доступе нескольких сессий к функциям, но этого не происходит. Жизненный цикл страницы ASP.Net гарантирует, что, если вы вручную не создадите дополнительные потоки, для заданного HttpContext и Session будет работать только одна функция за раз. Если пользователь каким-то образом отправляет два запроса примерно в одно и то же время, которые должны иметь одинаковый Session / HttpContext, один будет удерживаться средой выполнения ASP.Net до тех пор, пока другой не будет завершен. Если вы не хотите ссылаться на сеанс все время, вы можете создать в своем классе свойства, которые будут переносить переменные сеанса. См. @ ответ Панкаджа для примера.

2 голосов
/ 15 февраля 2012

В дополнение к ответу " Тим Шмельтер " ....

Вы можете создать BaseClass, который будет наследоваться от

System.Web.UI.Page

Поместите собственность как предложено "Тимом". Единственное изменение, которое вам нужно сделать, это изменить модификатор доступа на Protected, и вы должны удалить Public and Shared

Вы также можете оставить другие общие функции, свойства, которые мы можем использовать повторно и в других классах ... Точно так же вы можете создавать BaseControls и для пользовательских элементов управления

Наконец, наследуйте этот класс в веб-форме ....

Надеюсь, это поможет вам ...

Код базового класса

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
2 голосов
/ 15 февраля 2012

Во-первых, Session имеет пользовательскую область, поэтому он не будет перезаписан другим запросом.

Безопасен ли доступ к переменным сеанса asp.net через статические свойства статического объекта?

Вы можете инкапсулировать доступ в свойство:

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
0 голосов
/ 15 февраля 2012

Как правило, вы можете использовать разные места для хранения состояния приложения: Приложение (в масштабе приложения, сохраняет состояние в домене приложения), Сеанс (можно сохранить все, к чему будет обращаться текущий сеанс браузера), ViewState (переменные хранятся в скрытом вводе поле и будет размещаться на каждом постбэке). Конечно, вы также можете сохранить состояние в базу данных или файл. Я не уверен, чего вы хотите достичь, но похоже, что вы ищете что-то вроде ViewState.

Чтение Управление состоянием ASP.NET

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...