2012-09-17 2 views
3

저는 여러분이 저를 도울 수 있기를 바랍니다. 저는 MVC와 Entity Framework에 새로운 것이므로 주위를 둘러 보려고합니다. 나는 MVC4와 EF5를 사용하고있다. 여기 MVC 컨트롤러가 ViewModels에 바인딩되지 않습니다.

내가 두 엔티티, 사이트 및 SiteType이 내가 뭘하려고 오전의 개요 ...

입니다. 각 사이트는 여러 사이트 유형을 가질 수 있으므로 다 대다 관계를 유지합니다. Site, SiteType, SiteSiteType 테이블을 생성하여 일반적인 다 대다 관계로 데이터베이스를 설정했습니다. SiteSiteType에는 방금 SiteId 및 SiteType Id의 두 열이 포함되었습니다.

public partial class SiteType 
{ 
    public SiteType() 
    { 
     this.Sites = new HashSet<Site>(); 
    }  
    public int Id { get; set; } 
    public string Name { get; set; }  
    public virtual ICollection<Site> Sites { get; set; } 
} 

지금은 사용하고 SiteType

을 위해 ...

public partial class Site 
{ 
    public Site() 
    { 
     this.SiteTypes = new HashSet<SiteType>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Address { get; set; } 

    public virtual ICollection<SiteType> SiteTypes { get; set; } 
} 

그리고이 나는 엔티티 모델을 업데이트하고 완벽하게 사이트에 대해이처럼 내 개체를 만드는 일했다 강력하게 형식화 된보기, 대신 유형으로 사이트를 사용하여, 내가 만든 사용자 정의 ViewModel을 사용하고 있습니다.이 모양의 SiteViewModel ...

public class SiteViewModel 
{ 
    public Site Site { get; set; } 
    public bool WasPosted { get; set; } 
    public IEnumerable<SiteType> AvailableSiteTypes { get; set; } 
    public IEnumerable<SiteType> SelectedSiteTypes { get; set; } 
} 

그 이유는 설명 된대로 내가 MVC에 대한 CheckBoxList 확장을 사용할 것입니다 here

나는 그러나, 새로운 사이트를 만들고 여기에 SiteTypes를 추가하고 때

지금 모든 작품 때 편집을 시도하고 기존 레코드가 문제가 발생하기 시작했습니다. 여기

내가 가지고 있던 문제가 지금 내 컨트롤러 편집 GET 방식 ....

public ActionResult Edit(int id = 0) 
    { 
     Site site = _repository.GetSiteByID(id); 
     if (site == null) 
     { 
      return HttpNotFound(); 
     } 

     var model = new SiteViewModel(); 
     model.AvailableSiteTypes = _repository.GetSiteTypes(); 
     model.SelectedSiteTypes = site.SiteTypes; 
     model.Site = site; 

     return View(model); 
    } 

그리고 원래이처럼 보였다 포스트 방법 ....

[HttpPost] 
    public ActionResult Edit(SiteViewModel siteViewModel, int[] siteTypes) 
    { 

     if (ModelState.IsValid) 
     { 
      _repository.UpdateSite(siteViewModel.Site, siteTypes); 
      _repository.Save(); 
      return RedirectToAction("Index"); 
     } 

     siteViewModel.AvailableSiteTypes = _repository.GetSiteTypes(); 
     List<SiteType> selectedSiteTypes = _repository.GetSiteTypes(siteTypes).ToList(); 
     if (selectedSiteTypes.Count > 0) 
     { 
      siteViewModel.SelectedSiteTypes = selectedSiteTypes; 
     } 
     return View(siteViewModel); 

    } 

입니다했다 siteViewModel.Site가 업데이트 된 데이터가있는 양식에서 제대로 채워지지만 ID 열은 기존 레코드 였지만 새 레코드가 아니더라도 "0"으로 설정되었습니다. 나는 모든 것을 시도해 보았고 나는 왜 일을 할 수 없었습니다. 나는이 작업을 얻을 수있는 유일한 방법은 ...

HttpPost] 
    public ActionResult Edit(int id, SiteViewModel siteViewModel, int[] siteTypes) 
    { 
     siteViewModel.Site.Id = id; 
     ...... 

을에 "ID"매개 변수에 받아 수동으로이 같은 사이트 객체로 설정했다 그러나 그것은 얼마나 잘 모든 다른 바인딩에 비해 정말 지저분한 느낌 함께.

이렇게하는 유일한 방법입니까? 내가 놓친 게 있니?

내 게시물을 읽는 데 시간을내어 주셔서 감사합니다. 미안해 ... 내가 그것을 설명하는 방법 밖에 몰랐다, 너무 긴

답변

0

당신은 아마도 그런

@Html.HiddenFor(model => model.Site.Id) 

전체처럼 보이기 위해, 당신의 편집 페이지에서 뭔가를 SiteId를 추가해야 모델 바인딩/MVC 프레임 워크가 작동하고 ID가 유지되도록해야합니다.

2

실제로 엔티티를보기로 보내는 것은 결코 좋은 생각이 아닙니다.보기 모델은 사용자에게보기를 제공하는 데 필요한 데이터 만 가져야합니다. 각 Site에 대한 정보를보기에 전달해야하는 경우 별도의보기 모델 또는 DTO를 만들고 대신 전달합니다.

siteViewModel.Site = new SiteDto() 
{ 
    Id = site.Id, 
    Name = site.Name, 
    ... 
} 

엔티티는 데이터베이스에 다시 기록에 매핑하는 데 사용되는 속성을 숨긴, 당신이보기로/기관을 통과 할 때이 정보는 일반적으로 손실됩니다. 올바른 접근 방식은 필요한 모든 데이터를보기로 보내거나 더 이상 볼 수 없도록하는 것입니다. 그런 다음 POST 메소드에서 엔티티를 다시 가져 와서 뷰 모델의 변경 사항을 적용하십시오.

AutoMapper을 사용할 수 있습니다.

1

귀하의 경우에, 모델의 뷰 모델의 referance에 이름으로 결국 같은 문제에 붙어 :

[HttpPost] 
    public ActionResult Edit(SiteViewModel siteViewModel, int[] siteTypes) 
{ 
...you controller code. 
} 

변화 그것에 :

[HttpPost] 
    public ActionResult Edit(SiteViewModel model, int[] siteTypes) 
{ 
...you controller code. 
} 
관련 문제