[2008]Ajax Update Panel e ricaricamento della pagina

venerdì 23 aprile 2010 - 11.02

motogpdesmo16 Profilo | Senior Member

Buongiorno a tutti,
ho questo scenario nel mio applicativo web:
1-nella master page c'è un update panel contenente due textbox per Username e password, un pulsante per le operazioni di autenticazione e una label, inizialmente nascosta ma che viene visualizzata se il login è OK, adibita alla visualizzazione di un importo;
2-nella pagina ereditata dalla master c'è un update panel contenente una gridview popolata da righe ordine sulle quali posso effettuare la modifica delle quantità. L'esigenza dell'update panel è rappresentata dal fatto che nella griglia effettuo operazioni di editing/cancellazione e non mi andava giù il fatto che ad ogni postback mi ricaricasse interamente la pagina.

Altre specifiche: l'utente può agiungere righe ordine anche se non è loggato ma, quando effettua l'operazione di login, vado a verificare se per costui esistono degli ordini aperti. Se così fosse viene fatto un merge tra le righe ordine pre esistenti e quelle che sta inserendo in questo momento; se invece non ci sono ordini aperti, le righe attualmente presenti in griglia passeranno come ordine definitivo. (Spero di esser stato chiaro qui)
Quanto detto riesco a gestirlo senza alcun problema lato database.

Non riesco invece a far ricaricare la pagina affinchè la griglia visualizzi le righe aggiornate. Se premo F5 o Aggiorna sul browser funziona tutto perfettamente...ma questa operazione vorrei assolutamente evitarla,a ltrimenti non avrebbe senso credo la presenza degli update panel.
N.b.: specifico che l'operazione opposta, ossia l'apporto di modifiche alla griglia, mi fa aggiornare senza alcun problema l'update panel della pagina master

Mi auguro di aver esposto il problema in maniera abbastanza comprensibile e ringrazio anticipatamente per le eventuali risposte.

fguida Profilo | Expert

Se fai dell modifiche probabilmente devi rifare il bind della grid affinche esse vengano visualizzate dopo l' Update() del panel.
Magari lo hai omesso?

Francesco

motogpdesmo16 Profilo | Senior Member

Ci avevo pensato...infatti il metodo Update dell'Update Panel contenente la griglia sono riuscito a chiamarlo senza alcun problema solo che non sortisce alcun effetto.
Il binding della griglia, insieme ad altre operazioni strettamente necessarie, è demandato ad una Sub dichiarata nella pagina. Come potrei fare quindi a chiamare dalla master una sub dichiarata nella pagina ??

grazie per l'aiuto..

Gluck74 Profilo | Guru

c'è qualcosa che non mi torna.
l'utente come inserisce queste righe nella griglia? ovvero i controlli dove sono, nella master o nella pagina webForm?

perché la sub la devi chiamare dalla master? non sarebbe corretto.
Magari allega i file in questione così facciamo prima

motogpdesmo16 Profilo | Senior Member

Provo a chiarire meglio la situazione: nello specifico la web application che sto realizzando è un e-commerce.
Il carrello acquisti (e quindi griglia riepilogativa con prodotti, quantità, prezzo unitario, prezzo totale ecc) è possibile valorizzarlo sanche se non ho fatto login con le mie credenziali. Aggiungo i prodotti al carrello è successivamente finisco nella pagina di riepilogo dove vedo che la griglia man mano si popola.
N.b.: l'aggiunta dei prodotti al carrello è possibile farla solo ed esclusivamente da una pagina content che è ovviamente la pagina di dettaglio dell'articolo (foto, descrizione, prezzo ed altri dati).
Fin qui non ho nessun problema e penso di essere stato chiaro nell'esposizione.

L'utente potrebbe però concludere la procedura di acquisto e quindi deve loggarsi. Per loggarsi può utilizzare il pannello di login, presente nella master, sempre visibile in ogni pagina del sito. L'esigenza è questa: mettiamo che l'utente abbia già svolto, da anonimo, l'operazione di aggiunta dei prodotti, poi si sia loggato (quindi l'ordine anonimo si è agganciato all'ID del cliente) e infine abbia chiuso il browser. Resta un ordine "aperto". Se dovesse tornare sul sito da anonimo, può aggiungere altri prodotti al suo carrello e, all'atto del Login (Pressione del pulsante quindi), i prodotti attualmente presenti devono andare ad agganciarsi ad un eventuale suo ordine aperto. Tale operazione, lato database, riesco a farla senza problemi e funziona tutto perfettamente.

Il problema è questo: quando premo il pulsante di login, oltre ad effettuare le operazioni di aggancio delle righe che ho appena esposto, verifico se la chiamata proviene dalla pagina carrello e quindi chiamo questo codice:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

L'update dell'Update Panel si scatena (ho provato a buttarci dentro una label e a far cambiare un valore...funziona tutto perfettamente) MA non riesco a far scatenare il binding della griglia che rimane, tornando all'esempio di prima, con le sole righe inserite quando l'utente era anonimo. Premendo il tasto aggiorna del browser invece si scatena ovviamente il binding e vedo nella griglia l'ordine perfettamente agganciate.

Quindi, ricapitolando, poichè il metodo update funziona correttamente, il suggerimento dato nel precedente post da fguida è corretto: dovrei chiamare nuovamente il binding della griglia.
Come ho specificato nel mio precedente post, la SUB che richiama il binding della griglia è abbastanza complessa: al suo interno c'è un'altra SUB, che effettua di fatto il binding vero e proprio con tutte le istruzioni necessarie, ed altri calcoli che mi servono per aggiornare i totali lato database. Non posso mettere questa sub in un modulo/classe. come posso fare quindi a richiamare la sub della pagina content dalla pagina master??

Spero di esser stato chiaro.

Gluck74 Profilo | Guru

hai provato a fare questo?

If LCase(Request.Path.IndexOf("shopping-cart.aspx")) > 0 Then CType(CPHcontenuto.FindControl("CPHShop").FindControl(IDGriglia), GridView).DataBind() CType(CPHContenuto.FindControl("CPHShop").FindControl("UPGrdCarrello"), UpdatePanel).Update() End If

motogpdesmo16 Profilo | Senior Member

Si, avevo già provato ma senza successo e la griglia addirittura sparisce perchè non ci sono record al suo interno.
grazie comunque.

Gluck74 Profilo | Guru

Come non ci sono record?????????
ma la griglia a cosa è attaccata? SQLDataSource?

motogpdesmo16 Profilo | Senior Member

No..ho una procedura che provvede a riempire la griglia.
Cerco di spiegarmi meglio: al caricamento della content page carico la ormai celeberrima maxi procedura che carica la griglia ed effettua altre operazioni.
Il caricamento vero e proprio della griglia viene effettuato da questa Sub:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

i cui parametri sono: Griglia = Nome della mia GridView (GrdCarrello); cQuery = query da passare affinchè si popoli la griglia (e questa è contenuta nella maxi procedura); cNometab = nome della tabella sulla quale effettuo la query.

Dopo aver chiamato il metodo Databind come mi hai anche consigliato tu, vedo: "Nessun record presente in archivio".

Dove sbaglio??

Gluck74 Profilo | Guru

qindi, la griglia con i dati sta nella pagina content, mentre il login sta nella master.
Quando fai il login, controlli che la content sia quella dell'ordine e quindi vuoi ricaricare la griglia.

La maxi procedura se non sbaglio sta nella content.
se il login viene fatto dalla master, la pagina content dovrebbe essere ricaricata tutta, quindi io prima di tutto metterei un bel breckPoint sulla maxi procedura per vedere se in effetti viene richiamata, e soprattutto con quali parametri.

Cosa succede dopo il login? hai un redirect? hai solo un aggiornamento di un UpdatePanel?
forse se alleghi la pagina master e la content si fa prima

motogpdesmo16 Profilo | Senior Member

Si Gluck, hai capito tutto perfettamente.
Specifico che: il login può essere fatto dalla master ma, in quel momento, posso anche trovarmi non necessariamente nella content page del carrello.
Dopo il login effettuato dalla master page, viene chiamato ovviamente il Page_Load della content (che in questo momento non mi serve ancora perchè mostra dei dati "vecchi" in quanto non è stata ancora effettuata la procedura di accorpamento delle righe ordine di cui ho parlato nei precedenti post) e poi l'evento click del bottone login (dove effettivamente avviene, lato database, l'accorpamento).
Mi fermo qui al solito:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ho messo il breakpoint sulla riga da te indicata e, premendo F8, finisco sull' GrdCarrello_RowDataBound dove svolgo le operazioni di formattazione della griglia (aggiunta pulsante di modifica/cancellazione riga) ma ho la griglia già vuota perchè la tipologia di righe all'interno della griglia è: e.Row.RowType = EmptyDataRow {5}.
Ho tempestato tutti i metodi/eventi della pagina di breakpoint e ti assicuro che non passa da nessun'altra parte: il primo (e unico) è il RowDataBound.
Dopo l'esecuzione del RowDataBound si ritorna al controllo del login che chiama il metodo Update che provvede ad aggiornare l'update Panel. Aggiornamento che effettivamente riesce ma i dati in griglia non sono coerenti.

Come puoi vedere non è presente l'istruzione response.redirect, altrimenti non sarebbe giustificata la presenza di ajax e dei suoi update panel, ma richiamo solo il metodo Update dell'Update Panel.

Per il codice che mi avevi richiesto, ti allego le parti più significative:

Page_Load di Shopping-cart.aspx

If Not Page.IsPostBack Then 'valorizzo le griglie riempigriglie() 'altre operazioni... End If

Sub Riempigriglie:
Public Sub riempigriglie() 'Verifiche varie e operazioni lato database (omaggi, righe spesa ecc) 'Riempio griglia dettaglio cQuery = query che estrae le righe ordine riempigriglia(GrdCarrello, cQuery, "OrdRig") 'altre operazioni sul database (che funzionano correttamente!!) End Sub

Grazie!

Gluck74 Profilo | Guru

credo che il problema sia in questo punto:

If Not Page.IsPostBack Then 'valorizzo le griglie riempigriglie() 'altre operazioni... End If

quindi i dati da mettere nella griglia vengono "letti" solo se la pagina NON è in PostBack.
Nel momento che fai il login, questi dati non vengono più letti e la griglia per questo risulta vuota.

dovresti fare in modo di, dopo il login quando viene rigaricata la pagina content con il carrello, eseguire nuovamente il riempigriglie()

motogpdesmo16 Profilo | Senior Member

Si gluck, la tua teoria è giusta ma:
-quando sono nella pagina Shopping-Cart.aspx e premo il tasto di login della master, viene prima caricata la pagina content e poi scattano le funzionalità associate al pulsante login. Ovviamente questo è il funzionamento nativo e non lo posso modificare, solo che vorrei effettuare un nuovo caricamento della pagina content dopo aver premuto il pulsante login e senza possibilmente utilizzare il Response.redirect;
-ho provato a rimuovere la struttura IF per la pagina in postback ma non cambia nulla: nonostante abbia tappezzato l'evento LOAD della pagina di breakpoint, quando chiamo passo dall'ormai famoso codice

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

la pagina non viene ricaricata e, a differenza di prima, avendo tolto l'IF, vedo la griglia valorizzata ma sempre con gli ultimi prodotti perchè la procedura riempigriglie non viene richiamata mai.

Gluck74 Profilo | Guru

Dunque......

Al login viene fatto prima il Page_load sia della master che della content, qiundi l'evento login legato al pulsante.
è per questo che la griglia rimane o vuota (se lasci page.ispostback), o con i dati vecchi.

Giustamente.... non avevo considerato bene il ciclo.

Per risolvere mi vinene in mente:
lasci il controllo page.ispostback, ed aggiungi, magari nell'evento onPreRender della content, il controllo se l'utente è loggato, e rifai il CaricaGriglie;
oppure sposti tutto direttamente nel onPreRender della content.

Scusa la mia incertezza ma senza il codice non riesco bene a focalizzare.
Ciao, fammi sapere

motogpdesmo16 Profilo | Senior Member

Grazie infinite per la disponibilità e per la dritta, richiamando la procedura anche nell'evento PreRender son riuscito a risolvere il problema, lasciando pressochè inalterato tutto il codice.
Mi rendo conto, a posteriori, che non era affatto facile riuscire a interpretare correttamente la problematica tenendo conto che non avevi a disposizione il progetto.
Grazie ancora e a buon rendere!
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5