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)