2012-10-19 23 views
5

Ho un'applicazione ASP.NET MVC che visualizza un elenco di elementi. A mio avviso ciclo Vorrei sulle voci e rendere ogni elemento con vista parziale, in questo modo:Html.HiddenPer associazione a elemento errato

@foreach(var item in Model.items) 
{ 
    <li> 
     @Html.Partial("ItemView", item) 
    </li> 
} 

Nella vista voce, io avvolgere ogni elemento con un modulo che ha un pulsante 'Elimina', in questo modo:

@using(Html.BeginForm(...)) 
{ 
    @Html.HiddenFor(m=>m.Id) 
    <label>@Model.Name (@Model.Id)</label> 
    <input type="submit" value="Delete"/> 
} 

gli articoli sono reso correttamente, la pagina risultante ha una bella lista di tutti gli elementi con i loro nomi propri e ID visualizzati.

EDIT: Lo stesso accade con @Hidden, apparentemente, contrariamente a quanto ho scritto prima.

Inoltre, ciò accade solo la seconda volta che il modulo viene visualizzato (ovvero, dopo aver fatto clic su uno dei pulsanti Elimina), la prima volta che tutto funziona correttamente. I miei metodi di azione sono:

public ActionResult AllItems() 
{ 
    var model = new AllItemsModel(); 
    return PartialView(model); 
} 

public ActionResult Delete(DeleteModel model) 
{ 
    .... Perform the delete ... 
    return PartialView("AllItems", new AllItemsModel()); 
} 

Perché sta succedendo?

risposta

8

ho il sospetto che questo accade perché si dispone già di un parametro Id nelle RouteData:

public ActionResult SomeAction(int id) 
{ 
    var model = ... 
    return View(model); 
} 

e hai richiesto la pagina con /somecontroller/someaction/123. L'helper di HiddenFor ora usa l'Id dai valori del percorso e non l'id dell'elemento. Prova a rinominare la proprietà sul tuo modello di visualizzazione articoli con qualcosa di diverso da id. Ad esempio ItemId.

Un'altra possibilità è che il problema si verifica solo dopo il postback e non quando la pagina viene inizialmente visualizzata. Mostrare la tua azione POST potrebbe aiutare a esplorare ulteriormente questa possibilità.


UPDATE:

Bene, ora che avete mostrato le tue cose azione Posta sono molto più chiaro:

public ActionResult Delete(DeleteModel model) 
{ 
    .... Perform the delete ... 
    return PartialView("AllItems", new AllItemsModel()); 
} 

si sono fondamentalmente la creazione di una nuova vista del modello qui e passandolo alla vista parziale. Tuttavia, gli helper HTML utilizzano sempre il valore di ModelState durante l'associazione. E solo dopo questo il valore dal tuo modello di vista. Pertanto, se si intende modificare le proprietà sul modello all'interno dell'azione POST, assicurarsi di aver rimosso prima questo valore da ModelState. Nel tuo esempio dal momento che avete completamente graffiato l'intero modello vista (con la creazione di un new AllItemsModel()) si potrebbe cancellare l'intero ModelState:

public ActionResult Delete(DeleteModel model) 
{ 
    .... Perform the delete ... 

    // Clear the modelstate otherwise the view will use the values that were initially posted 
    // and not the values from your view model 
    ModelState.Clear(); 
    return PartialView("AllItems", new AllItemsModel()); 
} 

Questo comportamento è di progettazione e si applica a tutti i collaboratori del HTML, non solo l'helper HiddenFor.

+0

Wow, osservazione eccellente. Controllerò, penso di non averne uno. – zmbq

+0

Il tuo primo suggerimento non era corretto, ma il tuo secondo sembra promettente. Peccato non posso fare +1 su due volte ... lo controllerò. – zmbq

+0

Sì, era esattamente così. Molte grazie! – zmbq

Problemi correlati