Le modèle de type complexe MVC4 est nul après la publication

C’est mon modèle

public class AdministrationModel { public ssortingng FirstName { get; set; } public ssortingng LastName { get; set; } public ssortingng EmailAddress { get; set; } public bool IsApproved { get; set; } } 

C’est mon contrôleur

 public ActionResult GetTabContent(ssortingng id) { switch (id) { case "tab3": model = GetAllUsersInfo(); viewName = "Administration"; break; } return View(viewName); } private List GetAllUsersInfo() { List userList = new List(); foreach (MembershipUser user in Membership.GetAllUsers()) { UserProfile userProfile = UserProfile.GetUserProfile(user.UserName); userList.Add(new AdministrationModel { EmailAddress = user.Email, IsApproved = user.IsApproved, FirstName = userProfile.FirstName, LastName = userProfile.LastName }); } return userList; } 

Ceci est mon sharepoint vue

 @model List @using (Html.BeginForm("Administration", "Account")) { 
@foreach (AdministrationModel AM in Model) {
@Html.DisplayFor(modelItem => AM.FirstName)
@Html.DisplayFor(modelItem => AM.LastName)
@Html.DisplayFor(modelItem => AM.EmailAddress)
}
}

Lorsque l’utilisateur clique sur le bouton Mettre à jour le compte, il passe au contrôleur.

  [HttpPost] public ActionResult Administration(List model) { return View(); } 

à l’intérieur de cette méthode, le modèle est toujours nul. Cependant, la vue qui rend tout est parfait et montre ce que je veux montrer. Qu’est-ce que je fais mal?

Lorsque vous utilisez des collections, afin de les traiter correctement afin qu’elles soient liées au modèle sur post sans aucun travail supplémentaire sur les jambes, vous devez vous assurer qu’elles sont indexées correctement. Pour ce faire, utilisez une boucle for, du type:

 @for (int i = 0; i < Model.Count; i++) { @Html.HiddenFor(m => m[i].FirstName) @Html.HiddenFor(m => m[i].LastName) @Html.HiddenFor(m => m[i].EmailAddress) 
@Html.DisplayFor(m => m[i].FirstName)
@Html.DisplayFor(m => m[i].LastName)
@Html.DisplayFor(m => m[i].EmailAddress)
@Html.CheckBoxFor(m => m[i].IsApproved)
}

Cela devrait modéliser bind sans autre code 🙂

Edit: Désolé, j’ai oublié, displayFors par défaut, ne mettez pas les propriétés correctes pour la liaison de modèle, a ajouté hiddenFors pour les autres champs sans éditeur pour.

Edit2: Sur la base de votre autre question dans le commentaire, si elle était publique et si vous ne vouliez pas qu’elle modifie les valeurs masquées pour les valeurs à l’aide des outils de développement, essayez ce qui suit:

Ok, donc vous ne voulez pas qu’ils modifient les hiddenFors, c’est bien, mais vous aurez besoin d’une sorte d’identifiant pour que vous sachiez quel client est lequel, lorsque les données sont publiées, je suggère qu’au lieu de les avoir dans le code ci-dessus:

 @Html.HiddenFor(m => m[i].FirstName) @Html.HiddenFor(m => m[i].LastName) @Html.HiddenFor(m => m[i].EmailAddress) 

Remplacez-les par:

 @Html.HiddenFor(m => m[i].ClientId) 

De cette façon, vous ne publiez pas le prénom, le nom de famille ou l’adresse électronique, mais simplement une référence au client réel cochée, décochée.

Pour répondre à votre autre question dans le commentaire sur le suivi des valeurs d’origine, dans votre méthode de contrôleur, vous pouvez simplement aller chercher les valeurs d’origine dans la firebase database, puis voici comment vous pouvez détecter celles qui sont différentes, par exemple:

 [HttpPost] public ActionResult Administration(List model) { var originalMatches = GetAllUsersInfo(); var differences = (from o in originalMatches join c in model on o.ClientId equals c.ClientId where c.IsApproved != o.IsApproved).ToList() return View(); } 

Votre directive @model est incorrecte, il doit s’agir du nom de type complet.

Dans ce cas:

  @model TheNamespace.AdministrationModel 

Après votre question mise à jour.

Essayez d’utiliser:

 @Html.EditorFor(Model) 

Cela appellera un éditeur spécialisé pour votre liste.

http://blogs.msdn.com/b/nunos/archive/2010/02/08/quick-tips-about-asp-net-mvc-editor-templates.aspx

Si vous souhaitez renvoyer des éléments de la liste avec le modèle lors de la soumission, vous devrez utiliser une boucle for, pas une foreach.

La réponse de Matty va marcher.

Si vous voulez éviter de devoir spécifier des index (ce qui ne fonctionnerait pas si vous aviez un ICollection), vous pouvez définir un modèle enfant comme Xander l’a expliqué.

L’avantage, c’est que vous conservez tout votre fort typé intellisense dans la vue AdminContainerModel et MVC rattache les éléments à votre liste en retour pour vous.

Voici un exemple:

Modèle de l’éditeur principal (comme Xander l’a dit):

  @model IEnumerable @using (Html.BeginForm("Administration", "Account")) { 
@Html.EditorForModel()
}

AdminContainerModel Editor template (Ceci est appelé pour chaque élément de votre liste parce que vous avez appelé @ Html.EditorForModel:

 @model AdminContainerModel 
@Html.DisplayFor(modelItem => AM.FirstName)
@Html.DisplayFor(modelItem => AM.LastName)
@Html.DisplayFor(modelItem => AM.EmailAddress)