2011-04-06 97 views
1

好的,我已經結束了谷歌和StackOverflow和ASP.net - 我真的是唯一一個沒有得到這個的人嗎?MVC3實體框架4.1RC @ Html.DropDownListFor實際上是如何工作的?

粗糙的問題=我有一個引用Office實體的Employee實體。我以前能夠創建新員工(用錘子打敗我,忘記了代碼的工作原理),但現在我無法創建員工,也無法編輯現有員工。

現在,這是我學到的; 1)請確保您將辦公室列表添加到ViewBag的每個步驟 2)包括POST /編輯失敗;調用函數重新填充辦公室列表的ViewBag 3)我認爲(!!)你總是想設置Employee.Office,而不是Employee.Office.OfficeID;後者導致「是對象的關鍵信息的一部分,不能修改」的錯誤

所以,我的是,

具有以下方法的控制器;

private void AddOfficesToViewBag() 
    { 
     Dictionary<string, Office> list = new Dictionary<string, Office>(); 
     foreach (Office office in company.GetAllOffices()) 
      list.Add(office.ToString(), office); 

     SelectList items = new SelectList(list, "Value", "Key"); 
     ViewBag.OfficeList = items; 
    } 

創建一對看起來像;

public ActionResult Create() 
    { 
     if (company.Offices.Count() < 1) 
      return RedirectToAction("Create", "Office", (object) "You need to create one or more offices first"); 

     AddOfficesToViewBag(); 
     return View(new Employee()); 
    } 

    // 
    // POST: /Employee/Create 

    [HttpPost] 
    public ActionResult Create(Employee emp) 
    { 

     if (TryUpdateModel<Employee>(emp)) 
     { 
      company.Employees.Add(emp); 
      company.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      AddOfficesToViewBag(); 
      return View(emp); 
     } 
    } 

和編輯對,看起來像;

public ActionResult Edit(int id) 
    { 
     Employee emp = company.Employees.Single(e => e.EmployeeID == id); 
     AddOfficesToViewBag(); 

     return View(emp); 
    } 

    // 
    // POST: /Employee/Edit/5 

    [HttpPost] 
    public ActionResult Edit(int id, FormCollection collection) 
    { 
     Employee emp = company.Employees.Single(e => e.EmployeeID == id); 

     if (TryUpdateModel(emp)) 
     { 

      company.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      AddOfficesToViewBag(); 
      return View(emp); 
     } 
    } 

我會挑選編輯視圖,這是幾乎一樣的創建視圖;

@using(Html.BeginForm()){ @ Html.ValidationSummary(真) 員工

@Html.HiddenFor(model => model.EmployeeID) 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Office) 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownListFor(model => model.Office, (SelectList) ViewBag.OfficeList) 
     @Html.ValidationMessageFor(model => model.Office) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Name) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Name) 
     @Html.ValidationMessageFor(model => model.Name) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Age) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Age) 
     @Html.ValidationMessageFor(model => model.Age) 
    </div> 

    <p> 
     <input type="submit" value="Save" /> 
    </p> 
</fieldset> 

}

我要說的是,編輯,特別是,看起來幾乎沒有。它管理綁定到傳入的Employee對象,並將下拉列表設置爲適當的條目。 查看原始HTML源代碼顯示輸出值是Office.ToString()值。 對我而言,奇怪的是發生了一些魔法,它將Employee-> Office綁定到正確的條目,這使得Edit視圖可以正常工作,但是沒有選定項目的相應轉換(一個字符串,又名object-> ToString( ))到原始列表。

這似乎很基本(MVC/EF4/DropDownList),我覺得我失去了一些令人難以置信的根本。

所有的想法都表示讚賞。 問候 斯科特

回答

0

主要基於以下你可以

http://forums.asp.net/t/1655622.aspx/1?MVC+3+Razor+DropDownListFor+and+Model+property+from+EFCodeFirst

執行以下操作:

[HttpPost] 
public ActionResult Edit(Guid id, FormCollection collection) 
{ 
     CollectionViewModel cvc = new CollectionViewModel(); 
     cvc.Collection = _db.Collections.Where(c => c.CollectionId == id).Include("CollectionType").First(); 
     Guid collectionTypeId = Guid.Parse(collection["CollectionTypeId"].ToString()); 
     cvc.Collection.CollectionType =_db.CollectionTypes.Where(ct =>ct.CollectionTypeId == collectionTypeId).First(); 

     if (TryUpdateModel(cvc)) 
     { 
      _db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
} 

視圖模型

public class CollectionViewModel 
{ 
     public Collection Collection {get; set; } 
     public Guid CollectionTypeId { get; set; } 
     public SelectList CollectionTypes { get; set; } 
}