2010-07-18 3 views
1

Asp.net MVC 2 응용 프로그램을 빌드하고 있습니다.게시 할 때 내 모델의 속성에 SelectList의 값 채우기

저는 Team이라는 엔티티가 공개 속성을 통해 성별 및 등급이라는 다른 두 엔티티에 매핑됩니다.

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; } 
} 

다음과 같은 ViewModel이 있습니다.

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; } 
} 

내 양식이 예상대로 렌더링됩니다. Create 메서드를 디버깅 할 때 성 및 등급 속성이 내 Team 개체에서 NULL임을 알 수 있습니다.

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

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

내가 뭘 잘못하고 있니?

감사합니다, 에릭

답변

1

난 당신이 게시 다시보기 모델 클래스가 아닌 엔터티 클래스에 바인딩하는 것이 좋습니다. 엔티티 클래스를 반환 할 뷰 모델 클래스의 확장 메서드를 만듭니다.

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); 
    } 
} 

을 마지막으로보기 : 여기에 몇 가지 작업 코드는

<%@ 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

이 나에게 많은 이해된다. 희망을 조금씩 시도해 보겠습니다. –

+0

이것은 매우 잘 작동했습니다. 필요한 로직을 ViewModels에 두는 것이 일반적인 관행입니까? 그것은 내가 아직 읽지 않은 한 가지입니다. –

+0

아니요. 일반적인 관행은 아닙니다. 난 당신의 원본에 충실하려고했지만 실제로는 뷰 모델 생성자에서 리포지토리에 대한 호출을 리팩터링했습니다. 컨트롤러가 DB 또는 캐시에서 목록을 가져 와서 생성자에 전달할 가능성이 있습니다. 뷰 모델에 백엔드에 대해 전혀 알리지 않고 UI를 렌더링하는 데 필요한 데이터를 뷰에 제공하는 작업을 처리하도록하는 것이 좋습니다. –