2010-07-18 13 views
1

Je construis une application Asp.net MVC 2.Remplissage de propriétés sur mon modèle avec des valeurs d'une liste SelectList lorsque je poste

J'ai une entité appelée Team qui est mappée via les propriétés publiques à deux autres entités appelées Gender et Grade.

public class Team 
{ 
    public virtual int Id { get; private set; } 
    public virtual string CoachesName { get; set; } 
    public virtual string PrimaryPhone { get; set; } 
    public virtual string SecondaryPhone { get; set; } 
    public virtual string EmailAddress { get; set; } 
    public virtual Grade Grade { get; set; } 
    public virtual Gender Gender { get; set; } 
} 

J'ai un ViewModel qui ressemble à ceci.

public class TeamFormViewModel 
{ 

    public TeamFormViewModel() 
    { 
     Team = new Team(); 
     Grade = new SelectList((new Repository<Grade>()).GetList(),"ID", "Name",Team.Grade); 
     Gender = new SelectList((new Repository<Gender>()).GetList(), "ID", "Name", Team.Gender); 
    } 

    public Team Team { get; set; } 
    public virtual SelectList Grade { get; set; } 
    public virtual SelectList Gender { get; set; } 
} 

Ma forme est conforme à mes attentes. Lorsque je débogue la méthode Create, je vois que les propriétés Gender et Grade sont NULL sur mon objet Team.

[HttpPost, Authorize] 
    public ActionResult Create(Team team) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       (new Repository<Team>()).Save(team); 

      } 
      return RedirectToAction("Index"); 
     } 
     catch 
     { 
      return View(); 
     } 
    } 

Qu'est-ce que je fais mal?

Merci, Eric

Répondre

1

Je recommande que vous publiez et se lient de nouveau à une classe de modèle de vue plutôt que votre classe d'entité. Créez une méthode d'extension pour votre classe de modèle d'affichage qui renverra votre classe d'entité. Voici un code de travail:

public class Team 
{ 
    public virtual int Id { get; set; } 
    public virtual string CoachesName { get; set; } 
    public virtual string PrimaryPhone { get; set; } 
    public virtual string SecondaryPhone { get; set; } 
    public virtual string EmailAddress { get; set; } 
    public virtual Grade Grade { get; set; } 
    public virtual Gender Gender { get; set; } 
} 

public class Grade 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

public class Gender 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

public class TeamFormViewModel 
{ 
    public TeamFormViewModel() 
    { 
     var gradeList = (new Repository<Grade>()).GetList(); 
     var genderList = (new Repository<Gender>()).GetList(); 
     GradeList = new SelectList(gradeList, "Id", "Name"); 
     GenderList = new SelectList(genderList, "Id", "Name"); 
    } 

    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [DisplayName("Coach Name")] 
    [Required] 
    public string CoachesName { get; set; } 

    [DisplayName("Primary Phone")] 
    [DataType(DataType.PhoneNumber)] 
    [Required] 
    public string PrimaryPhone { get; set; } 

    [DisplayName("Secondary Phone")] 
    [DataType(DataType.PhoneNumber)] 
    public string SecondaryPhone { get; set; } 

    [DisplayName("Email Address")] 
    [DataType(DataType.EmailAddress)] 
    [Required] 
    public string EmailAddress { get; set; } 

    [DisplayName("Grade")] 
    [Range(1, 5)] 
    public int SelectedGradeId { get; set; } 

    [DisplayName("Gender")] 
    [Range(1, 5)] 
    public int SelectedGenderId { get; set; } 

    private int selectedGradeId = 0; 
    private int selectedGenderId = 0; 

    public SelectList GradeList { get; set; } 
    public SelectList GenderList { get; set; } 
} 

public static class TeamExtensions 
{ 
    public static Team ToTeam(this TeamFormViewModel viewModel) 
    { 
     return new Team 
     { 
     Id = viewModel.Id, 
     CoachesName = viewModel.CoachesName, 
     PrimaryPhone = viewModel.PrimaryPhone, 
     SecondaryPhone = viewModel.SecondaryPhone, 
     EmailAddress = viewModel.EmailAddress, 
     Grade = (new Repository<Grade>()) 
      .GetList() 
      .Where(x => x.Id == viewModel.SelectedGradeId) 
      .Single(), 
     Gender = (new Repository<Gender>()) 
      .GetList() 
      .Where(x => x.Id == viewModel.SelectedGradeId) 
      .Single() 
     }; 
    } 

    public static TeamFormViewModel ToTeamFormViewModel(this Team team) 
    { 
     return new TeamFormViewModel 
     { 
     Id = team.Id, 
     CoachesName = team.CoachesName, 
     PrimaryPhone = team.PrimaryPhone, 
     SecondaryPhone = team.SecondaryPhone, 
     EmailAddress = team.EmailAddress, 
     SelectedGradeId = team.Grade.Id, 
     SelectedGenderId = team.Gender.Id 
     }; 
    } 
} 

public class TeamController : Controller 
{ 
    public ActionResult Create() 
    { 
     var viewModel = new TeamFormViewModel(); 
     return View(viewModel); 
    } 

    [HttpPost] 
    public ActionResult Create(TeamFormViewModel viewModel) 
    { 
     if (ModelState.IsValid) 
     { 
     (new Repository<Team>()) 
      .Save(viewModel.ToTeam()); 
     } 
     return View(viewModel); 
    } 
} 

Et enfin, la vue:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Stack1.Models.TeamFormViewModel>" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Create</title> 
    <script type="text/javascript" src="/Scripts/jquery-1.4.1.js"></script> 
    <script type="text/javascript" src="/Scripts/MicrosoftAjax.js"></script> 
    <script type="text/javascript" src="/Scripts/MicrosoftMvcValidation.js"></script> 
</head> 
<body> 
    <% Html.EnableClientValidation(); %> 
    <% using (Html.BeginForm()) { %> 
    <%= Html.ValidationSummary() %> 
    <fieldset> 
     <legend>Fields</legend> 
     <%= Html.LabelFor(x => x.CoachesName) %> 
     <p> 
     <%= Html.TextBoxFor(x => x.CoachesName) %> 
     <%= Html.ValidationMessageFor(x => x.CoachesName) %> 
     </p> 

     <%= Html.LabelFor(x => x.PrimaryPhone)%> 
     <p> 
     <%= Html.EditorFor(x => x.PrimaryPhone) %> 
     <%= Html.ValidationMessageFor(x => x.PrimaryPhone)%> 
     </p> 

     <%= Html.LabelFor(x => x.SecondaryPhone)%> 
     <p> 
     <%= Html.EditorFor(x => x.SecondaryPhone) %> 
     <%= Html.ValidationMessageFor(x => x.SecondaryPhone)%> 
     </p> 

     <%= Html.LabelFor(x => x.EmailAddress)%> 
     <p> 
     <%= Html.EditorFor(x => x.EmailAddress) %> 
     <%= Html.ValidationMessageFor(x => x.EmailAddress)%> 
     </p> 

     <%= Html.LabelFor(x => x.SelectedGradeId)%> 
     <p> 
     <%= Html.DropDownListFor(x => x.SelectedGradeId, Model.GradeList) %> 
     <%= Html.ValidationMessageFor(x => x.SelectedGradeId)%> 
     </p> 

     <%= Html.LabelFor(x => x.SelectedGenderId)%> 
     <p> 
     <%= Html.DropDownListFor(x => x.SelectedGenderId, Model.GenderList) %> 
     <%= Html.ValidationMessageFor(x => x.SelectedGenderId)%> 
     </p> 
     <p> 
     <%= Html.HiddenFor(x => x.Id) %> 
     <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
    <% } %> 
</body> 
</html> 
+0

Cela fait beaucoup de sens pour moi. Je vais essayer cet essai dans un petit moment. –

+0

Cela a très bien fonctionné merci. Est-ce une pratique courante de mettre la logique requise dans les ViewModels? C'était une chose que je n'avais pas encore lue. –

+0

Non. Ce n'est certainement pas une pratique courante. J'ai essayé de coller un peu à votre original, mais en réalité, je refactoriserais les appels au référentiel dans le constructeur du modèle de vue. Je demanderais probablement au contrôleur d'appeler le référentiel pour obtenir les listes, à partir de la base de données ou du cache, et de les transmettre dans le constructeur. C'est une bonne idée de faire en sorte que vos modèles de vue ne sachent rien de votre backend et de leur laisser simplement le travail de fournir votre vue avec les données requises pour rendre l'interface utilisateur. –