0

我在顯示和保存導航屬性時遇到了問題。使用實體框架顯示和保存導航屬性4 MVC3

我有3個表:

RateProfile

  • RateProfileID
  • 摘要名稱

  • RateID
  • RateProfileID
  • PanelID

面板

  • PanelID
  • PanelName

我有這些和外鍵導航屬性的每個模型(即RatesRateProfile的導航屬性)。我有一個以RateProfile作爲模型的編輯頁面。在此頁面上,我有一個PanelID的下拉菜單。下拉式過濾器顯示哪些導航屬性(每個panelID有28個關聯的速率)。每當下拉列表發生變化時,它會發布到我的Edit方法(在繼續之前保存現有數據並顯示新選擇的panelID的費率​​)。

我只通過ViewBag將需要的費率記錄傳遞給我的列表。

我最初使用foreach循環

foreach(PDR.Models.Rate rate in ViewBag.Rates){ 
        @Html.HiddenFor(modelItem => rate.RateProfileID) 
        @Html.HiddenFor(modelItem => rate.RateID) 
        @Html.HiddenFor(modelItem => rate.PanelID) 

        @Html.EditorFor(modelItem => rate.Amount) 
        @Html.ValidationMessageFor(modelItem => rate.Amount) 
} 

隨着foreach循環,改變下拉時PanelID,即它將與每個面板的正確率顯示一切正常顯示。但是,我的費率都不會與我的模型一起傳遞迴我的控制器中的HTTPPost編輯方法。傳遞給我的控制器的RateProfile將在其Rates欄導航屬性中有0條記錄(視圖中有28條記錄)。

我被建議將foreach循環改爲for(int i ...)循環。顯然,foreach循環將所有的文本框命名爲同一個東西,而普通的for循環則根據索引命名它們。

使用for(int i ...)循環時,Rates導航屬性在傳遞給HTTPPost Edit方法時的確具有它的所有記錄,並且能夠根據我輸入的內容更新這些記錄。

但是...現在使用for(int i ...)循環,頁面將不會顯示基於panelID的正確記錄(即使已更改,它始終顯示默認panelID的記錄)。更令人瘋狂的是,如果我在我的觀點中提出了斷點,我發現正確的Rate記錄正在傳遞給View仍然存在。我發現正確的RateID/amount等都被放入Html幫助器中,但是當頁面實際顯示時,它顯示的是在更改下拉菜單之前存在的數據,而不是正在觀看的數據,它以調試模式填充。

這裏是因爲從foreach循環切換到正常的循環我使用的視圖代碼:

@{List<PDR.Models.Rate> rates = ViewBag.rates; 
     var count = rates.Count; 
     } 
    @for (int i = 0; i < count; i++) 
    { 
        @Html.HiddenFor(modelItem => rates[i].RateProfileID) 
        @Html.HiddenFor(modelItem => rates[i].RateID) 
        @Html.HiddenFor(modelItem => rates[i].PanelID) 

        @Html.EditorFor(modelItem => rates[i].Amount) 
        @Html.ValidationMessageFor(modelItem => rates[i].Amount) 
    } 

在我看來,檢查調試模式下的價值觀,我知道,正確率正在傳遞到ViewBag.rates根據panelID。問題是,儘管我可以在調試中逐步完成它,並且觀察它爲上述循環中的每個速率設置了RateID,PanelIDAmount的正確值,但頁面上實際顯示的值總是panelID == 1的值,然後傳遞給我的控制器的值始終是價格的值,其中panelID == 1而不是我傳遞給視圖的費率。

下面是編輯方法的代碼。我很確定這個問題在視圖中,因爲rateprofile(它應該是我的視圖中的模型)永遠不會獲得正確的導航屬性。

[HttpPost] 
    public ActionResult Edit(RateProfile rateprofile, int panelID) 
    { 

     var panels = db.Panels; 
     ViewBag.PanelDropDown = new SelectList(panels, "PanelID", "PanelName", panelID); 
     ViewBag.PanelID = panelID; 

     if (ModelState.IsValid) 
     { 
      db.Entry(rateprofile).State = EntityState.Modified; 

      foreach (Rate rate in rateprofile.Rates) 
      { 
       db.Entry(rate).State = EntityState.Modified; 
      } 
      db.SaveChanges(); 
     } 
     rateprofile = db.RateProfiles.Include(a => a.Rates).Where(a => a.RateProfileID == rateprofile.RateProfileID).Single(); //reloads the current rateprofile from the db 
     PopulatePanelDropDown(rateprofile, panelID); //populates the ViewBag.rates variable 

     return View(rateprofile); 
    } 

總結:

  • foreach循環在Rates:顯示一切正常基於panelID,但不會值傳遞給控制器​​。

  • for(int i ...)loop:只會顯示panelID == 1的值,並且不會根據panelID進行更新。將保存,但只有與panelID == 1相關的記錄。

+0

你不需要'for'循環,你可以使用'foreach'。訣竅是獲取輸入名稱屬性,當通過HTTP POST發送到服務器時,可以告訴默認模型綁定器如何構建複雜的viewmodel集合(for循環有助於此,但並非完全必要)。看看這些鏈接:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx http://blog.stevensanderson.com/2010/01/28/編輯一個變量長度列表aspnet-mvc-2樣式https://github.com/danludwig/BeginCollectionItem – danludwig 2012-07-19 04:06:53

+0

@danludwig:感謝您的鏈接。這是有道理的。 – 2012-07-28 23:22:34

回答

0

摸索了好幾個星期,並沒有找到這對我工作的任何答覆後,我終於只是改變了我的HTTPpost編輯方法重定向到我的HTTPGET編輯方法,而不是返回視圖。我將RateProfileID和panelID傳遞給我的HTTPget編輯方法,並且當面板下拉改變時,它沒有任何問題顯示正確的數據。