2010-09-10 21 views
5

Uso il mix di ListView + DataPager + ObjectDataSource.Come utilizzare le variabili globali in ObjectDataSource.SelectMethod?

Nell'implementazione del mio SelectMethod di ObjectDataSource mi piacerebbe accedere a una variabile globale impostata nell'evento PageLoad() (il metodo restituirà solo il numero corretto di elementi per pagina). Sebbene la variabile sia inizializzata in PageLoad(), sembra essere null in SelectMethod. Come posso cambiarlo?

<asp:ObjectDataSource ID="ItemsObjectDataSource" runat="server" EnablePaging="True" 
         SelectMethod="WrapSearchResults" SelectCountMethod="CountSearchResults" 
         TypeName="Catalogue"> 
         <SelectParameters> 
          <asp:QueryStringParameter Name="startRowIndex" QueryStringField="page" Type="Int32" DefaultValue="0" /> 
          <asp:Parameter Name="maximumRows" Type="Int32" DefaultValue="10" /> 
         </SelectParameters> 
    </asp:ObjectDataSource> 

SearchOption search; 
protected void Page_Load(object sender, EventArgs e) 
{ 
    search = new SearchOption(SessionParameters.Get(Session).User); 
} 

public IEnumerable<ResultWrapper> WrapSearchResults(int startRowIndex, int maximumRows) 
{ 
    search.Limit = maximumRows; <-- null pointer exception 
} 

risposta

9

Questo è un trucco comune con l'origine dati oggetto. Devi sempre ricordare questo:

L'ODS chiamerà il metodo specificato tramite Riflessione, non un'istanza specifica dell'oggetto. (A meno che non si specifica l'istanza da utilizzare da soli)

Il valore è nullo perché le ODS chiamato il metodo diretto e non è mai stata parte del ciclo di asp.net pagina di vita.

Se si ha realmente bisogno di fare ciò, rendere la variabile globale STATIC.

protected **static** SearchOption search; 

Se si dà un'occhiata alla traccia dello stack, appena prima dell'eccezione null si dovrebbero vedere le chiamate di riflessione del framework. Questo dovrebbe suggerirti cosa sta succedendo!

Ecco il riferimento MSDN:

http://msdn.microsoft.com/en-us/library/ms227436.aspx

Il controllo ObjectDataSource creerà un'istanza dell'oggetto sorgente, chiamare il metodo specificato, e smaltire l'istanza di oggetto tutte rientranti nell'ambito di un unico richiesta, se il proprio oggetto ha metodi di istanza anziché metodi statici (Condivisi in Visual Basic). Pertanto, il tuo oggetto deve essere stateless. Cioè, il tuo oggetto dovrebbe acquisire e rilasciare tutte le risorse richieste entro lo span di una singola richiesta.

È possibile controllare la modalità di creazione dell'oggetto di origine gestendo l'evento ObjectCreating del controllo ObjectDataSource. È possibile creare un'istanza dell'oggetto di origine e quindi impostare la proprietà ObjectInstance della classe ObjectDataSourceEventArgs su quell'istanza. Il controllo ObjectDataSource utilizzerà l'istanza creata nell'evento ObjectCreating anziché creare un'istanza autonomamente.

+0

OH MIO DIO! Molti anni e non si sono mai imbattuti in quel problema. Pensavo che la selezione fosse chiamata dopo 'pageRender', ecco perché era nullo .. NON! Grazie DUDE !!! +1 xoxoxo – ppumkin

+0

@ppumkin Sono contento di poterti aiutare! – asawyer

0

Il ASP.NET page lifecycle è probabilmente tale che Page_Load sta accadendo dopo l'inizializzazione del origine dati. Prova a utilizzare un evento precedente, ad esempio Page_Init o Page_PreInit.

0

si può provare anche l'evento OnSelect della sorgente di dati oggetto e inviare i parametri appropriati dal code-behind ci

7

Ho avuto lo stesso problema, ma ho trovato la soluzione.

Oppure si può gestire l'evento seguito in codice VB

Protected Sub PagingDataSource_ObjectCreating(ByVal sender As Object, ByVal e As ObjectDataSourceEventArgs) Handles PagingDataSource.ObjectCreating 
     e.ObjectInstance = Me 
    End Sub 

In questo modo si definisce l'istanza corrente di voi e tutta la sua classe di variabili. È un lavoro che ho provato da me stesso. Definisci anche il nome del metodo per ODS

<asp:ObjectDataSource ID="PagingDataSource" OnObjectCreating="PagingDataSource_ObjectCreating"