2009-09-16 22 views
6

Ho letto un sacco su questo problema, ma non riesco a capirlo.ASP.NET MVC DropDownList Valore selezionato Problema

Ho un elenco a discesa sulla mia vista che viene utilizzato per il paging. Scegli la pagina a cui vuoi andare e il modulo viene inviato. Quando viene restituita la vista, viene visualizzata la pagina richiesta. Il menu a discesa cambia per riflettere la pagina appena mostrata. Funziona bene

Il mio problema è questo: Ho 2 pulsanti di invio, uno per la pagina successiva e uno per la pagina precedente. Nel controller, se uno dei sottomessi è stato premuto, la pagina # deve essere incrementata o decrementata di 1. Ciò sta accadendo e viene visualizzata la pagina corretta dei dati. Ma, l'elenco a discesa non lo farà, NO MATERIA COSA FACCIO, rifletterà il nuovo numero di pagina quando viene mostrata la vista.

In sostanza, se il menu a discesa viene modificato dall'utente, rifletterà tali modifiche quando viene inviato di nuovo dopo l'invio di un modulo. Se cambio pagina # a livello di codice, il menu a discesa non cambierà, anche se viene visualizzata la pagina corretta dei dati.

Ecco il metodo di azione:

public ActionResult Results(TechSearch search, string NextPage, string PrevPage) 
{ 
    if (NextPage != null) search.Page++; 
    if (PrevPage != null) search.Page--; 

    int resultCount = search.GetResultCount(Desk); 

    List<int> pages = new List<int>(); 
    int pageCount = (int)Math.Ceiling((decimal)resultCount/search.PageSize); 
    for (int i = 1; i <= pageCount; i++) pages.Add(i);   

    ViewData["pages"] = new SelectList(pages, search.Page);    
    ViewData["pageCount"] = pageCount; 

    return View(search); 
} 

E qui è la parte rilevante della vista:

<input type="submit" value="<" name="PrevPage" /> 
Page 
<%=Html.DropDownList("Page",(SelectList)ViewData["pages"]) %> 
of 
<%=ViewData["pageCount"]%> 
<input type="submit" value=">" name="NextPage" /> 

prega di aiuto.

EDIT

Pagina 333 di Pro ASP.NET MVC Framework by Steven Sanderson:

Come controlli di input ottenere i loro valori

Ognuno dei [i Helpers HTML per il rendering Controlli di ingresso] cerca di popolarsi, cercando per un valore nei seguenti luoghi, nell'ordine di priorità:

  1. ViewData.ModelState [ "controlName"]. Value.RawValue parametro
  2. valore passato al metodo di supporto HTML, o se hai chiamato un di sovraccarico che non include un parametro di valore , poi Viewdata .Eval ("controlName")

ModelState è un'area di memorizzazione temporanea che ASP.NET MVC utilizza per mantenere valori tentate entrata più vincolanti e convalida errori. Si noti che è nella parte superiore dell'elenco di priorità, , pertanto i suoi valori sovrascrivono qualsiasi cosa che potrebbe impostare in modo esplicito. Questa convenzione significa che è possibile passare un parametro di valore esplicito per agire come valore iniziale o predefinito dell'helper; tuttavia, quando esegue nuovamente la visualizzazione dopo un errore di convalida , l'helper ha il valore e mantiene qualsiasi valore inserito dall'utente nella preferenza a tale valore predefinito.

Ho verificato che ViewData.ModelState ["Pagina"]. Valore.RawValue contiene il numero di pagina imprevisto che mi assilla. Qual è il modo migliore per aggirare questo problema?

+1

+1 Uso davvero piacevole delle stringhe e del collegamento del modello per effettuare un'analisi analizzabile di quale pulsante di invio è stato premuto. –

+0

@Dan - Grazie. L'ho preso da Pro ASP.NET MVC Framework di Steven Sanderson nella sezione su Wizards and Multistep Forms (pg 396) –

+1

Il libro di Steven Sanderson è molto buono. – RichardOD

risposta

4

Il problema era che ModelState teneva la dropdownlist del passato in termini di valore. Per i controlli di input HtmlHelper, ModelState ha la priorità rispetto ai valori impostati in modo esplicito durante la visualizzazione di un valore nel controllo di input.

Ecco quello che ho fatto nel mio metodo di azione per risolvere il problema:

ModelState.Remove("Page"); 
return View(search); 

Sono interessato a sentire altri modi di fissare il mio problema.

+1

Inserire il numero di pagina direttamente nello stato modello all'interno dell'azione anziché cancellarlo. La tua lista di selezione verrà generata solo dall'elenco di pagine. – Neal

0

Modificare il valore selezionato con javascript al clic del pulsante successivo o precedente, subito prima del postback.

+0

L'ho fatto prima che facessi la mia domanda e che se ne è occupata, ma perché non funziona diversamente? –

+0

Il browser memorizza nella cache la selezione degli utenti. Usando il javascript si modifica la selezione degli utenti (e quindi l'impressione del brower della selezione) prima di fare il postback. L'alternativa sarebbe quella di inserire un valore nell'intestazione della pagina che non specifica la memorizzazione nella cache. Questo potrebbe o non potrebbe essere quello che ti serve ... –

+0

Il browser non dovrebbe essere in cache. Il metodo form è un GET. Ciò significa che il parametro di pagina viene inviato nell'url, il che rende l'url univoco. –

0
  1. Sei sicuro che si ha la garanzia che almeno uno di NextPage o PrevPage sarà nullo? (E non si ottiene nulla di strano, come String.Empty forzando un incremento e decremento?)
  2. Potrebbe .LastOrDefault() sostituito con appena .Last() e siete sicuri che non sta assegnando default(int)-search.Page?
+0

1.) Sì, sono sicuro. 2.) Tale linea di codice non è rilevante per il problema. –

0

Il seguente testo ha qualche effetto?

ViewData["pages"] = new SelectList(pages, 
            pages.FirstOrDefault(p => p == search.Page)); 

Sostituzione

ViewData["pages"] = new SelectList(pages, search.Page); 
+0

Questo non ha avuto alcun effetto. –

Problemi correlati