2013-02-25 48 views
0

首先,我們再次抱怨在此網站上多次報道過的話題 - 就像我嘗試的那樣,我無法獲得我的代碼工作。ASP.net MVC3使用DropDownList在Veiw中選擇外鍵

我有以下的模型類:

public class ProjectsTable { 
    public int ID {get; set;} 
    public String ProjectName {get; set;} 
    ... 
    public virtual Manager Manager_Id {get; set;} // Stores foreign key of Manager 
} 

public class Manager { 
    public int ID {get; set;} 
    public String ManagerName {get; set;} 
    ... 
    public virtual ICollection<ProjectsTable> Projects {get; set;} 
} 

的ProjectsTable控制器類包含以下方法來兼作顯示和編輯頁面:

private SynthContext db = new SynthContext(); 
... 

// GET: /ProjectsTable/Parameters/5 
public ActionResult Parameters(int id) { 
    ProjectsTable projectstable = db.ProjectsTable.Find(id); 
    ViewBag.Manager_Id = new SelectList(db.Manager, "ID", "ManagerName"); 
    return View(projectstable); 
} 

// POST: /ProjectsTable/Parameters/5 
public ActionResult Parameters(ProjectsTable projectstable) { 
    if(ModelState.IsValid) { 
    db.Entry(projectstable).State = EntityState.Modified; 
    db.SaveChanges(); 
    return RedirectToAction("Parameters"); 
    } 
    ViewBag.Manager_Id = new SelectList(db.Manager, "ID", "ManagerName"); 
    return View(projectstable); 
} 

最後,Parameters.cshtml包含以下代碼來顯示下拉列表

@model Synth.Models.ProjectsTable 
... 
<fieldset> 
... 
    <div class="editor-lable"> 
    @Html.LabelFor(model => model.Manager_ID) 
    </div> 
    <div class="editor-field"> 
    @HTML.DropDownList("Manager_ID", String.Empty) 
    </div> 
    <input type="submit" value="Update"> 
</fieldset> 

當我測試th e代碼,我可以導航到/ProjectsTable/Parameters/x沒有任何問題;正確生成包含經理名稱列表的下拉列表。但是,當我單擊「更新」按鈕時,Manager_ID將以紅色突出顯示,表示更改尚未註冊。我可以通過導航到/ProjectsTable/list來確認更改沒有註冊,但我發現沒有任何更改已生效。

我試過添加@Html.ValidationMessageFor(Model.Manager_ID),結果總是「值'x'無效」,其中x是一個有效的ID值(我已根據數據庫檢查過它)。

我看過生成的HTML源代碼,在那裏也看不到任何錯誤。

我懷疑我需要用@HTML.DropDownListFor替換@HTML.DropDownList,但我無法弄清楚它需要什麼參數才能正常工作。 編輯 - 我現在設法得到DropDownListFor工作,但問題仍然存在。幫助我解決此問題的相關問題可能是如何查看發送回服務器的發佈數據。

任何幫助將不勝感激。

感謝你的所有提前...

Chopo

回答

0

所以我終於找到了問題。它與視圖或控制器無關。顯然我沒有正確地寫出模型:外鍵應存儲爲int?以及指向相關模型的指針。

public class ProjectsTable { 
    public int ID {get; set;} 
    public String ProjectName {get; set;} 
    ... 

    public int? ManagerID {get; set;} // Stores foreign key of Manager 
    public virtual Manager Manager // I have no idea if this line does anything 
} 

public class Manager { 
    public int ID {get; set;} 
    public String ManagerName {get; set;} 
    ... 
    public virtual ICollection<ProjectsTable> Projects {get; set;} 
} 

雖然不是必需的,視圖也使用本功能的好處:

Html.DropDownListFor(model => model.Manager_ID, ViewBag.Manager_Id as SelectList, String.Empty) 

功能@HTML.DropDownList("ManagerID", String.Empty)也可以,但是爲了它這樣做的ViewBag對象的名稱是從通過控制器(ManagerID)必須與模型的外鍵完全匹配。這是令人費解和令人困惑的,因爲我的口味。我更喜歡強類型的方法。

爲了完整起見,我包括完全校正代碼:

控制器:

private SynthContext db = new SynthContext(); 
... 

// GET: /ProjectsTable/Parameters/5 
public ActionResult Parameters(int id) { 
    ProjectsTable projectstable = db.ProjectsTable.Find(id); 
    // The following line has been amended, but this change is not strictly necessary 
    ViewBag.m_id = new SelectList(db.Manager, "ID", "ManagerName", projectstable.ManagerID); 
    return View(projectstable); 
} 

// POST: /ProjectsTable/Parameters/5 
public ActionResult Parameters(ProjectsTable projectstable) { 
    if(ModelState.IsValid) { 
    db.Entry(projectstable).State = EntityState.Modified; 
    db.SaveChanges(); 
    return RedirectToAction("Parameters"); 
    } 
    ViewBag.m_id = new SelectList(db.Manager, "ID", "ManagerName", projectstable.ManagerID); 
    return View(projectstable); 
} 

檢視:

@model Synth.Models.ProjectsTable 
... 
<fieldset> 
... 
    <div class="editor-lable"> 
    @Html.LabelFor(model => model.ManagerID) 
    </div> 
    <div class="editor-field"> 
    Html.DropDownListFor(model => model.ManagerID, ViewBag.m_id as SelectList, String.Empty) 
    @Html.ValidationMessageFor(model => model.ManagerID) 
    </div> 
    <input type="submit" value="Update"> 
</fieldset> 
0

我想你混淆了自己,因爲你有一個模型屬性Manager_Id和viewBag對象Manager_Id。您的modelState錯誤引用了model屬性,而不是下拉列表中的任何綁定到viewBag對象的值。我建議重新命名您ViewBag爲了避免混淆(或更好,但不使用ViewBag在所有),並加入一個隱藏字段的模型屬性:

@Html.HiddenFor(m => m.Manager_Id) 

作爲一個側面說明,從你的描述你的上面的故障排除工作,我還建議在Visual Studio中進行舒適的調試,設置斷點和檢查值。從長遠來看,這會讓你的生活變得更加輕鬆。

+0

有趣的是,一旦予重命名viewbag到'm_id'和更改CSHTML代碼到'@ HTML.DropDownList(「m_ID」,String.Empty)'我不再有任何驗證錯誤,但現在我的控制器不會註冊和存儲我在DropDownList中選擇的內容。我真的可以使用'DropDownList',還是我需要切換到'DropDownListFor',如果是的話,我需要輸入什麼參數。 – Chopo87 2013-02-25 18:16:12

+0

DropDownListFor的文檔是[here](http://msdn.microsoft.com/en-us/library/system.web.mvc.html.selectextensions.dropdownlistfor(v = vs.108).aspx)。 – 2013-02-25 18:21:21

+0

ddl值不在控制器中,因爲viewBag對象不是要傳遞的模型的一部分。 – 2013-02-25 18:23:06

相關問題