Проблема с ошибкой gridview, paging и object reference not set

Я застрял со следующей проблемой. Я пытаюсь реализовать базовый постраничный набор результатов GridView, который подключается к базе данных Oracle. Сам по себе GridView и постраничные результаты работают нормально. Проблема возникает, когда я пытаюсь поместить его в класс макета страницы, который у нас есть на работе.

У нас есть ClassA, который наследуется от Page и является корпоративным стандартом. Затем у меня есть ClassB, который наследуется от ClassA и включает в себя код для конкретного приложения. Страница, на которой находится GridView, наследуется от ClassB. Кажется, все это отлично работает на других страницах, и я не думаю, что это источник проблемы, но я подумал, что упомяну об этом.

Что происходит, так это то, что при первой загрузке страницы с GridView все выглядит нормально. Запрос выполняется, и отображаются первые 10 записей с номерами для разбиения по страницам ниже. Когда я нажимаю «2» или любую другую страницу, я получаю «желтый экран смерти» со следующим сообщением: «Ссылка на объект не указывает на экземпляр объекта». Объект, на который ссылается эта строка ошибки, — это «Я», объект Page (ASP.pagename_aspx в отладчике). Я не считаю, что точная строка, в которой он терпит неудачу, так важна, потому что я поменял порядок нескольких операторов, и он просто терпит неудачу на самом раннем из них.

Я проверил с помощью отладчика, и он выглядит нормально, только на странице 1 он работает нормально, а на странице 2 - нет.

Я реализовал событие PageIndexChanging (опять же, оно работает само по себе, если я удаляю наследование от ClassB. Кроме того, если я пытаюсь наследовать непосредственно от ClassA (полностью минуя ClassB), я все еще получаю проблему.

Любые идеи? Спасибо.


person Community    schedule 23.09.2008    source источник
comment
Вы получаете эту ошибку, когда PageA наследуется от system.web.ui.page?   -  person Chad Braun-Duin    schedule 10.10.2008


Ответы (4)


Я столкнулся с похожей ситуацией, когда в базе (ClassA в вашем примере) были переменные, которые были настроены для обработки всех битов подкачки и сортировки, а GridView был подключен к событиям, которые использовали эти переменные. Неправильная установка переменных базового класса на моей странице вызвала точно такую ​​​​же ошибку.

person Harper Shelby    schedule 23.09.2008
comment
Я пытался сделать его как можно более простым, поэтому вся конфигурация GridView находится непосредственно на странице во время разработки (за исключением результатов команды SQL). - person ; 23.09.2008

Когда у меня были подобные проблемы в прошлом, это обычно была проблема с привязкой данных (не вызывать DataBind() в нужное время, поэтому, когда он пытается просмотреть следующую страницу, DataSource имеет значение null).

person Sam Schutte    schedule 23.09.2008
comment
Я считаю, что DataBind() используется правильно, поскольку разбиение по страницам отлично работает изолированно (минус код ClassA/ClassB). Я также прошел через отладчик, и ошибка возникает задолго до использования GridView. - person ; 23.09.2008

Я согласен с @DotNetDaddy в том, что вам нужно убедиться, что вы установили источник данных для обратной передачи, так как это почти наверняка является причиной «забавного» желтого экрана смерти. Ниже приведен очень простой пример, демонстрирующий сортировку и разбиение по страницам для GridView в .NET 2.0+.

Ниже приведена точная разметка, необходимая для правильной работы этого gridview с моим кодом vb.

<asp:GridView ID="gridSuppliers" EnableViewState="false" runat="server" OnPageIndexChanging="gridSuppliers_PageIndexChanging" AutoGenerateColumns="false" AllowPaging="true" AllowSorting="true" CssClass="datatable" CellPadding="0" CellSpacing="0" BorderWidth="0" GridLines="None">...</asp:GridView>

Далее идет файл кода программной части с необходимой реализацией сортировки/разбиения по страницам для привязки данных на основе коллекции.

Partial Public Class _Default
    Inherits System.Web.UI.Page
    Implements ISupplierView

    Private presenter As SupplierPresenter

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
        MyBase.OnInit(e)
        presenter = New SupplierPresenter(Me)
    End Sub

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

    Protected Sub gridSuppliers_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles gridSuppliers.PageIndexChanging
        gridSuppliers.PageIndex = e.NewPageIndex
        presenter.PopulateSupplierList()
    End Sub

    Private Sub gridSuppliers_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs) Handles gridSuppliers.Sorting
        If DirectCast(ViewState("PreviousSortExpression"), String) = e.SortExpression Then
            If DirectCast(ViewState("PreviousSortDirection"), String) = "Ascending" Then
                e.SortDirection = System.Web.UI.WebControls.SortDirection.Descending
                ViewState("PreviousSortDirection") = "Descending"
            Else
                e.SortDirection = System.Web.UI.WebControls.SortDirection.Ascending
                ViewState("PreviousSortDirection") = "Ascending"
            End If
        Else
            e.SortDirection = System.Web.UI.WebControls.SortDirection.Ascending
            ViewState("PreviousSortDirection") = "Ascending"
        End If
        ViewState("PreviousSortExpression") = e.SortExpression

        Dim gv As GridView = DirectCast(sender, GridView)
        If e.SortExpression.Length > 0 Then
            For Each field As DataControlField In gv.Columns
                If field.SortExpression = e.SortExpression Then
                    ViewState("PreviousHeaderIndex") = gv.Columns.IndexOf(field)
                    Exit For
                End If
            Next
        End If
        presenter.PopulateSupplierList()
    End Sub

#Region "ISupplierView Properties"
    Private ReadOnly Property PageIsPostBack() As Boolean Implements ISupplierView.PageIsPostBack
        Get
            Return Page.IsPostBack
        End Get
    End Property

    Private ReadOnly Property SortExpression() As String Implements ISupplierView.SortExpression
        Get
            If ViewState("PreviousSortExpression") Is Nothing Then
                ViewState("PreviousSortExpression") = "CompanyName"
            End If
            Return DirectCast(ViewState("PreviousSortExpression"), String)
        End Get
    End Property

    Public ReadOnly Property SortDirection() As String Implements Library.ISupplierView.SortDirection
        Get
            If ViewState("PreviousSortDirection") Is Nothing Then
                ViewState("PreviousSortDirection") = "Ascending"
            End If
            Return DirectCast(ViewState("PreviousSortDirection"), String)
        End Get
    End Property

    Public Property Suppliers() As System.Collections.Generic.List(Of Library.Supplier) Implements Library.ISupplierView.Suppliers
        Get
            Return DirectCast(gridSuppliers.DataSource(), List(Of Supplier))
        End Get
        Set(ByVal value As System.Collections.Generic.List(Of Library.Supplier))
            gridSuppliers.DataSource = value
            gridSuppliers.DataBind()
        End Set
    End Property
#End Region

End Class

И, наконец, класс презентатора, используемый в коде программной части.

Public Class SupplierPresenter
    Private mView As ISupplierView
    Private mSupplierService As ISupplierService

    Public Sub New(ByVal View As ISupplierView)
        Me.New(View, New SupplierService())
    End Sub

    Public Sub New(ByVal View As ISupplierView, ByVal SupplierService As ISupplierService)
        mView = View
        mSupplierService = SupplierService
    End Sub

    Public Sub OnViewLoad()
        If mView.PageIsPostBack = False Then
            PopulateSupplierList()
        End If
    End Sub

    Public Sub PopulateSupplierList()
        Try
            Dim SupplierList As List(Of Supplier) = mSupplierService.GetSuppliers()
            SupplierList.Sort(New GenericComparer(Of Supplier)(mView.SortExpression, mView.SortDirection))
            mView.Suppliers = SupplierList
        Catch ex As Exception
            Throw ex
        End Try
    End Sub
End Class

** класс, необходимый для сортировки универсальной коллекции, на которую ссылается презентатор.

Imports System.Reflection
Imports System.Web.UI.WebControls

Public Class GenericComparer(Of T)
    Implements IComparer(Of T)

    Private mDirection As String
    Private mExpression As String

    Public Sub New(ByVal Expression As String, ByVal Direction As String)
        mExpression = Expression
        mDirection = Direction
    End Sub

    Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements System.Collections.Generic.IComparer(Of T).Compare
        Dim propertyInfo As PropertyInfo = GetType(T).GetProperty(mExpression)
        Dim obj1 As IComparable = DirectCast(propertyInfo.GetValue(x, Nothing), IComparable)
        Dim obj2 As IComparable = DirectCast(propertyInfo.GetValue(y, Nothing), IComparable)
        If mDirection = "Ascending" Then
            Return obj1.CompareTo(obj2)
        Else
            Return obj2.CompareTo(obj1)
        End If
    End Function
End Class
person Toran Billups    schedule 12.10.2008

Я потерял свой первоначальный незарегистрированный логин, который я использовал для публикации этого вопроса.

Как бы то ни было, ответ Харпер Шелби оказался верным. В этом базовом классе была неустановленная переменная (специальный объект, являющийся нашим корпоративным стандартом), которая вызвала проблему (и никакого полезного сообщения об ошибке).

Если это увидит администратор или кто-то с нужными полномочиями, вы можете пометить ответ Харпера как единственный и закрыть его. Спасибо всем за помощь.

person user933    schedule 29.10.2008