#asp.net #gridview
Вопрос:
Я столкнулся со следующей проблемой. Я пытаюсь реализовать базовый подкачанный набор результатов GridView, который подключается к базе данных Oracle. Само по себе представление сетки и результаты на странице работают нормально. Проблема возникает, когда я пытаюсь поместить ее в класс макета страницы, который у нас есть на работе.
У нас есть ClassA, который наследуется от Page и является корпоративным стандартом. Затем у меня есть ClassB, который наследуется от ClassA и который включает код для конкретного приложения. Страница, на которой находится представление сетки, наследуется от ClassB. Все это, кажется, прекрасно работает на других страницах, и я не думаю, что это источник проблемы, но я подумал, что упомяну об этом.
Что происходит, так это то, что при первой загрузке страницы с видом сетки все выглядит нормально. Запрос выполняется, и отображаются первые 10 записей с номерами для подкачки ниже. Когда я нажимаю на «2» или любую другую страницу, я получаю «желтый экран смерти» со следующим сообщением: «Ссылка на объект не установлена для экземпляра объекта». Объектом, на который ссылается эта строка ошибки, является «Я», объект страницы (ASP.pagename_aspx в отладчике). Я не верю, что точная строка, на которой он выходит из строя, настолько важна, потому что я поменял порядок нескольких утверждений, и он просто выходит из строя на самом раннем.
Я проследил с помощью отладчика, и он выглядит нормально, только на странице 1 он работает нормально, а на странице 2 он выходит из строя.
Я реализовал событие PageIndexChanging (опять же, оно работает само по себе, если я удаляю наследование из ClassB. Кроме того, если я попытаюсь наследовать непосредственно от ClassA (полностью минуя ClassB), у меня все равно возникнет проблема.
Есть какие-нибудь идеи? Спасибо.
Комментарии:
1. Вы получаете эту ошибку, когда PageA наследует от system.web.ui.page?
Ответ №1:
Я столкнулся с аналогичной ситуацией, когда в базе (ClassA в вашем примере) были переменные, настроенные для обработки всех битов подкачки и сортировки, а представление сетки было подключено к событиям, которые использовали эти переменные. Не установка правильных переменных базового класса на моей странице привела к точно такой же ошибке.
Комментарии:
1. Я пытался сделать это как можно проще, поэтому конфигурация GridView находится непосредственно на странице во время разработки (за исключением результатов команды SQL).
Ответ №2:
Когда у меня были подобные проблемы в прошлом, обычно это была проблема привязки данных (не вызов DataBind() в нужное время, поэтому, когда он пытается просмотреть следующую страницу, источник данных равен нулю).
Комментарии:
1. Я считаю, что DataBind() используется правильно, так как подкачка прекрасно работает изолированно (за вычетом кода ClassA/ClassB). Я также прошел через отладчик, и ошибка возникает задолго до того, как используется GridView.
Ответ №3:
Я согласен с @DotNetDaddy в том, что вам нужно убедиться, что вы установили источник данных на post-back, так как это почти наверняка является причиной «веселого» желтого экрана смерти. Ниже приведен очень простой пример, показывающий сортировку и подкачку для представления сетки в .NET 2.0
Ниже приведена точная разметка, необходимая для правильной работы этого представления сетки с моим кодом 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
И, наконец, класс presenter, используемый в коде
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
Ответ №4:
Я потерял свой первоначальный незарегистрированный логин, который я использовал для публикации этого вопроса.
Во всяком случае, ответ Харпера Шелби оказался правильным. В этом базовом классе была неустановленная переменная (пользовательский объект, являющийся нашим корпоративным стандартом), которая вызвала проблему (и не было полезного сообщения об ошибке).
Если администратор или кто-то с соответствующими полномочиями увидит это, вы можете отметить ответ Харпера как единственный и закрыть это. Спасибо всем за их помощь.