NullReference на объекте в коде после AsyncPostBack с использованием UpdatePanel - PullRequest
0 голосов
/ 20 февраля 2012

Я создаю простую игру в веб-приложении ASP.NET/VB.NET. В игре есть пользовательский интерфейс, состоящий из нескольких кнопок ImageButton.

Код веб-страницы, стоящий за файлом, содержит экземпляр объекта game , который будет управлять каждым ходом игрока.

Все работало, когда методы объекта Game были общими.

Проблема возникла после рефакторинга, чтобы заставить игровой объект работать как экземпляр вместо общего класса. Теперь, когда действие возвращается к коду, экземпляр игрового объекта имеет вид Ничего .

Я подозреваю, что это как-то связано с состоянием просмотра, но ... Гугл не помог.

Кодовые биты:

Public Class _Default
        Inherits System.Web.UI.Page

        Private _gamePanel As Panel
        Private _updatePanel as UpdatePanel
        Private _game as Game

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            If Not Page.IsPostBack Then

                'create a new instance of the game object on first loading page
                _game = New Game(width, height, cellsToWin)

            End If

            ' DisplayGameBoard() does the following:
            '  * Add images to the GameBoard panel inside of the GameBoardUpdatePanel
            '  * Attach click event handler to each image (addressOf located in this 
            '      code behind file
            '  * DisplayGameBoard() works fine the first time but fails on
            '      subsequent post backs because there is no game object instance
            Me.DisplayGameBoard()

        End Sub

(со страницы директивы)

Language="vb" 
AutoEventWireup="false" 
CodeBehind="Default.aspx.vb" 
Inherits="Game._Default" 
ValidateRequest="false" 
EnableEventValidation="false"
EnableViewState="true"

(панель обновления на веб-странице)

    <asp:UpdatePanel ID="GameBoardUpdatePanel" 
                     runat="server" 
                     UpdateMode="Conditional" 
                     RenderMode="Block" 
                     EnableViewState="true"
                     ViewStateMode="Enabled" 
                     ChildrenAsTriggers="true" >

        <ContentTemplate>

            <asp:Label ID="PlayerName"
                        runat="server"></asp:Label>

            <asp:Panel ID="GameBoard"
                        runat="server"
                        cssclass="gameBoard"></asp:Panel>

        </ContentTemplate>
    </asp:UpdatePanel>

1 Ответ

0 голосов
/ 20 февраля 2012

Это не ViewState, это просто время жизни экземпляра _Default.

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

Каждый запрос к странице приводит к созданию нового экземпляра класса _Default, а при создании ответа экземплярвыброшенный.Ссылка на экземпляр класса Game, который вы сохранили на странице, также отбрасывается, и вы теряете любой способ получить к нему доступ.

Если вы хотите сохранить экземпляр Gameкласс, вы можете сохранить его в коллекции Session, которая зависит от пользователя:

If Not Page.IsPostBack Then

  'create a new instance of the game object on first loading page
  _game = New Game(width, height, cellsToWin)
  ' store the reference in the user session
  Session("game") = _game

Else

  ' get the reference back from the user session
  _game = DirectCast(Session("game"), Game)

End If

Однако вы должны быть осторожны с тем, сколько вы храните в сеансе пользователя.Обычно объекты, создаваемые на странице, являются недолговечными (т. Е. Миллисекундами), поэтому они оказывают небольшое влияние на ресурсы сервера.Все, что вы храните в пользовательском сеансе, будет очень долгим в сравнении.Подумайте, насколько велик объект Game, и действительно ли вам нужно сохранить весь объект или вы можете хранить только информацию, необходимую для его воссоздания для каждого запроса.

...