Gli elementi ListBox riorganizzati con JavaScript causano errori di convalida degli eventi sul postback

StackOverflow https://stackoverflow.com/questions/212988

Domanda

Ho creato un controllo di scambio di elementi che consiste in due caselle di riepilogo e alcuni pulsanti che mi consentono di scambiare elementi tra i due elenchi. Lo scambio avviene tramite javascript. Sposto anche gli elementi su e giù nell'elenco. Fondamentalmente quando sposto gli elementi nella casella di riepilogo a destra, conservo le chiavi di dati degli elementi (GUID) in un campo nascosto. Al postback ho semplicemente letto i GUID dal campo. Tutto funziona alla grande ma al postback ottengo la seguente eccezione:

  

Argomento postback o callback non valido. La convalida dell'evento è abilitata usando in configurazione o & Lt;% @ Page EnableEventValidation = & Quot; true & Quot; % Gt &; in una pagina. Per motivi di sicurezza, questa funzione verifica che gli argomenti relativi agli eventi di postback o callback provengano dal controllo server che li ha originariamente resi. Se i dati sono validi e previsti, utilizzare il metodo ClientScriptManager.RegisterForEventValidation per registrare i dati di postback o callback per la convalida.

Ho preparato una domanda di prova. Tutto quello che devi fare è scaricare l'archivio ed eseguire il progetto. Nella pagina Web selezionare i 3 elementi, premere Aggiungi tutto, quindi spostare il terzo elemento in alto di un livello e quindi premere & Quot; Pulsante & Quot ;. L'errore verrà visualizzato. La disattivazione della convalida dell'evento non è assolutamente accettabile. Qualcuno può aiutarmi, ho già trascorso due giorni senza trovare una soluzione.

APPLICAZIONE DI PROVA

È stato utile?

Soluzione 3

La prima opzione porterà un notevole sovraccarico. Ho definito il mio controllo personalizzato listbox derivato dalla classe listbox ed eseguito una sostituzione dei dati di loadpostback:

public class CustomListBox : ListBox
{
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        return true;
    }
}

L'uso di questo invece della normale casella di riepilogo nel mio controllo utente ha risolto il problema, tuttavia ci sono dei rischi associati al mio approccio?

Altri suggerimenti

Il problema è che lo stato di visualizzazione salvato dell'elenco e i dati ricevuti sul postback non corrispondono. Il problema della convalida dell'evento è molto probabilmente solo uno dei possibili problemi che potrebbero apparire a causa di questo approccio. L'architettura dei moduli web non consente questo tipo di utilizzo e, molto probabilmente, ci saranno più problemi con questo approccio, anche se riuscirai a evitare il problema di convalida dell'evento. Hai diverse alternative:

1) Il più semplice è fare la logica di scambio sul server invece di usare javascript. In questo modo lo stato di visualizzazione verrà conservato tra i postback e il sovraccarico aggiunto di più round trip al server potrebbe non essere un problema.

2) Se il round trip al server è un problema, scrivere un controllo server che gestisca il proprio stato di visualizzazione. Questo è ovviamente un approccio molto avvincente.

3) Un approccio di medio livello potrebbe essere quello di utilizzare due semplici elenchi HTML (basta scrivere i tag HTML senza usare i controlli asp.net) e mantenere sul lato client da JavaScript un elenco di ID in un campo nascosto. Al post-back basta analizzare il campo nascosto ed estrarre l'id ignorando gli elenchi HTML.

Andrei con 1 se non ci sono argomenti SERI contro questo.

Alcune opzioni possibili:

  • Se possibile, disabilitare ViewState nei due elenchi. Senza ViewState, il server non saprà quali fossero i valori originali e quindi non si verificherà alcun errore. Con questo approccio, dovrai ripopolare gli elenchi (a causa della mancanza di ViewState) e potrebbe essere necessario tenere traccia della selezione manualmente o dovrai popolare gli elenchi durante la fase OnInit.

  • Disattiva la convalida dell'evento (se puoi)

  • Popola entrambi gli elenchi completamente sul lato server e utilizza lo script lato client (javascript) per rimuovere le voci dai due elenchi come richiesto.

Per caso, l'hai già provato? Fallo ogni volta che sbagli con l'elenco in alcun modo.

document.getElementById("listbox").selectedIndex = -1;

Si lamenta perché l'elemento selezionato in un elenco non era presente nell'elenco quando veniva visualizzato. Prendi in considerazione l'utilizzo di PageMethods tramite AJAX per ripristinare i dati nel modulo anziché in PostBack. Oppure utilizza un controllo non di input per conservare i dati, come elenchi non ordinati tra cui spostare gli elementi dell'elenco avanti e indietro. Puoi inserire i GUID in intervalli nascosti all'interno dell'elemento elenco dove puoi trovarli se necessario.

In alternativa, è possibile utilizzare un HtmlSelect sul lato server al posto di un ListBox per aggirare il problema di convalida dell'evento. Soprattutto, potresti essere in grado di lasciare intatto gran parte del tuo codice (ad es. La logica della popolazione dell'elenco è la stessa di ListBox).

<select runat="server" id="myList" multiple="true" />

È possibile ignorare l'evento Render per registrare tutti i possibili elementi della casella di riepilogo con entrambe le caselle di riepilogo. In questo modo, indipendentemente dagli elementi in cui vengono spostati, la convalida li sta aspettando.

protected override void Render(HtmlTextWriter writer)
{
  foreach (DictionaryEntry entry in ColumnConfig) {          
    Page.ClientScript.RegisterForEventValidation(lstbxColumnsToExport.UniqueID,(string)entry.Key);
    Page.ClientScript.RegisterForEventValidation(lstbxNonExportColumns.UniqueID,(string)entry.Key);
  }
  base.Render(writer);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top