使用UpdatePanel在AsyncPostBack之后的代码中的对象的NullReference

时间:2012-02-20 17:16:00

标签: asp.net ajax vb.net updatepanel nullreferenceexception

我正在ASP.NET / VB.NET网络应用程序中构建一个简单的游戏。游戏的UI由几个ImageButtons组成。

网页的代码隐藏文件包含游戏对象的实例,该对象将管理玩家每次转弯。

当Game对象的方法被共享时,一切都有效。

重构后发生问题,使游戏对象作为实例而不是共享类工作。现在,当操作返回到后面的代码时,游戏对象的实例是 nothing

我怀疑这与视图状态有关,但呃...... Google没有帮助。

代码位:

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 :(得分:0)

它不是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对象的大小,以及是否真的需要保留整个对象,或者只保留为每个请求重新创建它所需的信息。