2012-09-17 57 views
3

我希望你能幫助我,我對MVC和實體框架相當陌生,並試圖讓我的頭腦。我正在使用MVC4和EF5。MVC控制器沒有綁定ViewModels

這裏是什麼,我試圖做一個概述...

我有兩個實體,網站和SiteType。每個網站可以有多個SiteType,因此它們具有多對多關係。我通過創建3個表格,Site,SiteType和SiteSiteType來建立典型的多對多關係的數據庫。 SiteSiteType只包含2列,SiteId和SiteType Id。

我更新了實體模型和它的工作完美地創造我的實體像這樣的網站...

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

這對於SiteType

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

現在我使用的是強類型視圖,但是,而不是使用網站作爲類型,我使用我創建一個自定義的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; } 
} 

這樣做的原因是我想用CheckBoxList的擴展MVC描述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); 
    } 

而且POST方法最初看上去像這樣....

[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」,即使它是一個現有的記錄,而不是一個新的。我已經嘗試了一切,但我無法弄清楚爲什麼。我能得到它的工作的唯一途徑是採取一種「ID」參數,手動將其設置爲這樣的站點對象...

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

但相比有多好一切結合它只是感覺真的很亂一起。

這是唯一的方法來做到這一點?我錯過了什麼嗎?

非常感謝您花時間閱讀我的文章。對不起它實在是太長了,我不知道該怎麼解釋呢?

回答

0

您可能需要在編輯頁面中添加SITEID,看起來像

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

那麼整個模型綁定/ MVC框架應該工作並確保id保留。

2

將實際實體發送到您的視圖永遠不是一個好主意,您的視圖模型應該只會將它需要的數據呈現給用戶。如果您需要將有關每個Site的信息傳遞給視圖,請創建一個單獨的視圖模型或DTO,並將其傳遞給

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

實體都隱藏這是用來回映射記錄在數據庫中的屬性,當你從視圖通過實體/這個信息通常會丟失。正確的方法是發送所有需要的數據,而不再需要。然後在您的POST方法中,重新拉動您的實體並應用視圖模型中的更改。

如果您發現自己在各處都這樣做,則可以使用AutoMapper

1

卡住了同樣的問題,與視圖模型全球化志願服務青年名稱型號結束了,對於你的情況:

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

將其更改爲:

[HttpPost] 
    public ActionResult Edit(SiteViewModel model, int[] siteTypes) 
{ 
...you controller code. 
} 
相關問題