Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di EnSa
    Registrato dal
    Apr 2009
    Messaggi
    191

    [ASP.NET MVC3 c#] ActionResult Edit

    Ho questo codice nell'edit
    codice:
            //
            // GET: /ModOrd/Edit/5
     
            public ActionResult Edit(int id)
            {
                User user = db.User.Find(id);
                return View(user);
            }
    
            //
            // POST: /ModOrd/Edit/5
    
            [HttpPost]
            public ActionResult Edit(User user)
            {
                if (ModelState.IsValid)
                {
                    db.Entry(user).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                return View(user);
            }
    Questo codice mi funziona perfettamente se nella pagina edit ho un solo elemento da modificare..


    Come posso procedere se volessi visualizzare una tabella con la lista di tutti gli utenti e con i campi modificabili e al click del pulsante salva mi si aggiornino tutti i record modificatisenza modificarne uno alla volta??


    Grazie mille

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Se per esempio voglio modificare una lista dei primi 5 user
    codice:
    public ActionResult EditPrimiCinque()
            {
                User user = db.User.Take(5).ToList();
                return View(user);
            }
    
    
            [HttpPost]
            public ActionResult EditPrimicinque(List<User> users)
            {
                if (ModelState.IsValid)
                {
                    foreach(User u in users)
                        db.Entry(user).State = EntityState.Modified;
    
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                return View(user);
            }
    Affinche questo funzioni il modelbinder deve poter capire attraverso le variabili POST che si vuole bindare una collection. A tal proposito il metodo EditorFor fa quasi tutto in automatico, solo bisogna rinunciare al foreach in favore del for nella view:

    codice:
    @for(int i = 0; i < Model.Count; i++) {
            <tr>
                <td>
                    @Html.EditorFor(m => m[i].Nome)
                </td>
                <td>
                    @Html.EditorFor(m => m[i].Cognome)
                </td>
            </tr>
    In questo modo tutte le textbox avranno un attributo name univoco che permetterà (e segnalerà) al model binder di bindare l'intera lista di oggetti.

  3. #3
    Utente di HTML.it L'avatar di EnSa
    Registrato dal
    Apr 2009
    Messaggi
    191
    Funziona perfettamente

    unico inconveniente è:

    come posso fare per raggruppare i dati del model??

    prima utilizzavo il seguente codice per visualizzare i risultati raggruppati:

    codice:
    @foreach (var grp in Model.User.GroupBy(x => x.Ruolo))
        {
    
            <tr>
                <td class="grp" colspan="3">
                    @Html.Encode(grp.Key)
                </td>
            </tr>
            foreach (var item in grp)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.ID)
                    </td>
                    <td class="center">
                        @Html.DisplayFor(modelItem => item.Nome)
                    </td>
                    <td class="center">
                        @Html.DisplayFor(modelItem => item.Password)
                    </td>
                </tr>
            }
        }

    Grazi mille

  4. #4
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    In questo scenario per usare il metodo che ti ho detto su devi fare un po di "sporcature" tipo rinunciare al groupBy e fare il raggruppamento a mano ordinando per ruolo e giocare un po' con qualche if.

    Ci sarebbe un altro sistema piu appropriato che invece di usare l'indice usa l'id dell'utente. Bisogna usare dei campi nascosti ma non ricordo esattamente come si fa. Domani mattina dall'ufficio lo rileggo dal manuale e vedo se puo risolvere il problema.

  5. #5
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    l'altra soluzione non va bene perciò dovresti fare il raggruppamento a mano. Per prima cosa nella action GET devi ordinare tutto per RUOLO (e poi eventualmente tramite ThenBy per altri criteri). Poi nella view fai in questo modo: Ti posto la mia (quella con cui ho fatto le prove) poi te la adatti un po tu:

    codice:
    @using (Html.BeginForm())
    {
    <table>
        <tr>
            <th>
                Nome
            </th>
            <th>
                Cognome
            </th>
    
        </tr>
        @{ string current = string.Empty; }
        @for(int i = 0; i < Model.Count; i++) {
            if (Model[i].Ruolo != current)
            {
                <tr>
                    <td colspan="3">@Html.DisplayFor(m => m[i].Ruolo)</td>
                </tr>
                current = Model[i].Ruolo;
            }
            <tr>
                <td>
                    @Html.HiddenFor(m => m[i].Ruolo)
                    @Html.EditorFor(m => m[i].Nome)
                </td>
                <td>
                    @Html.TextBoxFor(m => m[i].Cognome)
                </td>
            </tr>
        }
    </table>
    <input type="submit" value="Invia" />
    }
    prima del for dichiaro un current che è la stringa del nome del ruolo corrente. Ovviamente all'inizio è vuota. Ad ogni ciclo comparo current con il ruolo dell'i-esimo utente e se è diverso allora stampo a video la riga del ruolo.
    L'hiddenFor ruolo è necessario altrimenti non verrà passato il ruolo tra le variabili post e quindi non sarà bindato.

    Se invece vorresti modificare anche il ruolo invece che l'hiddenfor ci metti, in un <TD> tutto suo un Editorfor.

  6. #6
    Utente di HTML.it L'avatar di EnSa
    Registrato dal
    Apr 2009
    Messaggi
    191
    Funziona Perfettamente!!!


    Grazie mille!!!

  7. #7
    Utente di HTML.it L'avatar di EnSa
    Registrato dal
    Apr 2009
    Messaggi
    191
    Ora mi da il seguente errore in db.SaveChanges()

    codice:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
    codice:
            [HttpPost]
            public ActionResult EditPrimicinque(List<User> users)
            {
                if (ModelState.IsValid)
                {
                    foreach(User user in users)
                        db.Entry(user).State = EntityState.Modified;
    
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                return View(user);
            }

    Qualche idea???

  8. #8
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    quel tipo di eccezione contiene una dictionary nelle proprietà che memorizza un elenco di tutti i problemi riscontrati durante il SaveChanges, mentre sei in debug con il mouse vai sull'eccezione e guarda li dentro ci sara esattamente il problema.

    Tieni presente che le entità user in questo caso conterranno SOLO le proprietà bindate dalla view in altre parole sono entità il cui stato è dato solo dai valori che sono stati trattati nella view è non è detto che il loro stato sia consistente. Se per esempio gli utenti hanno una proprietà Citta il cui tipo è collegato al relativo entityset (quindi una tabella) succede che tutte le proprietà Citta dopo il binding saranno null perche non le hai usate nella view e quindi dopo il post non sono state bindate. Sono quasi certo che il problema che riscontreraii sarà legato a questo aspetto.

    Devi far conto che la lista che ti arriva non sia fatta dalle vere entità da modificare ma che sia semplicemente un contenitore di dati con cui andrai a modificare le VERE entità. Con l'id di ogni user "contenitore" devi tirare fuori dal context (db) l'user ed assegnare ogni proprietà dello user "contenitore" alla corrispondente del vero user per poi assegnare a quest'ultimo lo stato di Modified.

    Per non fare confusione tra user intesi come "contenitori" e user dallo stato "consistente" è bene usare i DTO (o ViewModel). Si scrive molto piu codice, è una pratica anche abbastanza pallosa da fare ma si lavora in modo certamente piu pulito (se non sbaglio anche la guida mvc di html.it ne parla)

  9. #9
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Integro con un pezzettino di codice, cio che bisogna cambiare (se il problema è quello che penso io) è il foreach:

    codice:
        foreach(User vmu in users)
        {
            User user = db.User.Find(vmu.ID); //Pesco il vero user attraverso l'id dell'user "contenitore"
            if (null == user)
                throw InvalidOperationException(); // L'user nel frattempo è sparito sicuramente c'è stato un errore di concorrenza e tutta l'operazione dovrebbe essere anullata. Potresti gestirla anche in modo piu pulito questa cosa per esempio aggiungendo un errore al modelstate.
    
            user.Nome = vmu.Nome;
            user.Cognome = vmu.Cognome;
            //e cosi via per tute le proprietà da modificare...
     
            db.Entry(user).State = EntityState.Modified;
        }
    
        db.SaveChanges();

  10. #10
    Utente di HTML.it L'avatar di EnSa
    Registrato dal
    Apr 2009
    Messaggi
    191
    grazie mille ...

    un ultima cosa:

    nel caso in cui dovessi avere molti dati da ripassare tramite l'httppost ci impiega parecchio tempo ... e vorrei metterci una progressbar o una gif da visualizzare durante la procedura del post

    sapresti consigliarmi qualcosa???

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.