Domanda

Supponi di creare un modulo utilizzando ASP.NET MVC con un numero dinamico di elementi modulo.

Ad esempio, è necessaria una casella di controllo per ciascun prodotto e il numero di prodotti cambia di giorno in giorno.

Come gestiresti i dati del modulo che vengono inviati al controller? Non puoi impostare i parametri sul metodo di azione perché non sai quanti valori del modulo torneranno.

È stato utile?

Soluzione

Assegna a ciascuna casella di controllo un valore univoco:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" 
 name="<%= "approveCheck" + recordId %>" type="checkbox" />

Quindi analizza l'elenco dei valori del modulo nell'Azione, dopo l'invio:

foreach (var key in Request.Form.Keys)
    {
        string keyString = key.ToString();
        if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase))
        {
            string recNum = keyString.Substring(12, keyString.Length - 12);

            string approvedKey = Request.Form["approveCheck" + recNum];
            bool approved = !String.IsNullOrEmpty(approvedKey);
            // ...

Non è necessario passare i valori del modulo come argomenti; puoi semplicemente ottenerli da Request.Form.

Un'altra opzione: scrivere un raccoglitore di modelli per modificare l'elenco in un tipo personalizzato per l'invio del modulo.

Altri suggerimenti

Per la risposta di Craig .. è più sicuro. Ci sono stranezze per la pubblicazione di più elementi del modulo con lo stesso nome. Aggiungo che sarebbe saggio avvolgere la logica che rende la "collezione" dei controlli in modo simile a WebForms. I moduli Web antepongono il nome del controllo contenitore e aggiungono un indice. Ad esempio, in un ripetitore gli elementi del modulo all'interno sarebbero chiamati (qualcosa come) RepeaterName_Element1, RepeaterName_Element2. Quando vai a prendere gli elementi, devi usare FindControl o qualcosa del genere.

A seconda dei leganti che stai utilizzando, questo dovrebbe funzionare:

<%var i = 0;
  foreach (var product (IList<ProductSelection>)ViewData["products"]) {%>
      <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%>
      <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%>
      <%=product.Name%><br/>
<%}%>

... che risulterà in HTML simile a questo (notare la notazione dell'array sui nomi):

<input name="products[0].Id" type="hidden" value="123">
<input name="products[0].Selected" type="checkbox">
Widget
<input name="products[1].Id" type="hidden" value="987">
<input name="products[1].Selected" type="checkbox">
Gadget

... e il metodo controller che gestisce il post:

public ActionResult SelectProducts(IList<ProductSelection> products)
{
     ...
}

Al momento dell'associazione, il parametro products conterrà due istanze di ProductSelection.

Un avvertimento è che non ho usato la nuova associazione predefinita per oggetti complessi. Piuttosto sto usando NameValueDeserializer o CastleBind, entrambi da MvcContrib. Si comportano entrambi in questo modo. Immagino che il binding nella Beta funzionerà allo stesso modo.

A seconda dei tuoi dati, potresti produrre un 'CheckboxList' (che non è più possibile nelle versioni più recenti) e usare un parametro string [] , oppure puoi impostare più moduli e basta modificare l'azione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top