1

我正在開發一個小應用程序,以便更好地理解MVC3和Razor的工作方式。我使用的是MVC3,所有代碼都是自動生成的(通過T4的dbContext,通過添加控制器的控制器,來自EDMX模型的Databese ...)。DropDownlistFor使用MVC3創建新實體

在我的模型我有這個簡單的模型: http://i.stack.imgur.com/nyqu4.png

public partial class Application 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ApplicationType ApplicationType { get; set; } 
} 

public partial class ApplicationType 
{ 
    public int Id { get; set; } 
    public string Type { get; set; } 
} 

正如你所看到的,ApplicationType基本上是一個枚舉(恥辱,EF 4對枚舉不支持)。所以,在我的ApplicationController我有這樣的:

public ActionResult Create() 
{ 
    ViewBag.AppTypes = new SelectList(db.ApplicationTypes.OrderBy(c => c.Type), "Id", "Type"); 
    return View(); 
} 

[HttpPost] 
public ActionResult Create(Application application) 
{ 
    if (ModelState.IsValid) 
    { 
     db.Applications.Add(application); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(application); 
} 

在我看來:

@Html.DropDownListFor(model => model.ApplicationType.Id, (SelectList)ViewBag.AppTypes, "Choose...") 

現在我面臨兩個問題:未填充

1)ApplicationType:

As @ Html.DropDownListFor只呈現一個簡單的選擇,它填充ID,但不填充Type屬性,如下所示(對不起,我可以' T型柱圖像作爲我是新來的):

http://i.stack.imgur.com/96IR1.png

你可以看到,ID是確定的圖片,但類型是空的。

我在做什麼錯了?

2)複製數據

的第二個問題是,如果我在調試期間手動填寫Type屬性(模擬正確的工作流的情況),ApplicationType被複制到數據庫中,而不是僅參照一箇舊的註冊表。

那麼,我怎樣才能使@ Html.DropDownListFor引用一個先前的現有項目,而不是創建一個新的?

感謝您的幫助!

回答

0

我相信你所犯的錯誤是在視圖中使用你的域模型,並假設在後期整個模型應該完全綁定並準備存儲在數據庫中。雖然可以在視圖中使用域模型,但最好單獨創建查看模型

例如:

public class ApplicationViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public SelectList ApplicationTypeList { get; set; } 
    public string ApplicationTypeId { get; set; } 
} 

在你看來:

@Html.DropDownListFor(model => model.ApplicationTypeId, Model.ApplicationTypeList , "Choose...") 

在你的控制器

[HttpPost] 
public ActionResult Create(ApplicationViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     Application application = new Application() 
     { 
      Id = model.Id, 
      Name = model.Name, 
      ApplicationType = db.ApplicationTypes 
       .First(a => a.Id == model.ApplicationTypeId); 

     }; 
     db.Applications.Add(application); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(model); 
} 

然後,您可以驗證您的視圖模型的ApplicationTypeId對應於實際應用鍵入模型狀態驗證的一部分。您可以使用AutoMapper加快將視圖模型轉換爲域模型的過程。

+0

令人驚歎!所以我的問題不在於代碼本身,而在於MVC如何工作。這很容易理解和遵循。 – 2012-04-26 17:45:02

+0

順便說一句,我使用的是不同的方法: 公共的ActionResult創建(應用程序) { 如果(ModelState.IsValid) { INT appTypeID = Convert.ToInt32(ModelState中[ 「ApplicationType.Id」]值。 AttemptedValue); application.ApplicationType = db.ApplicationTypes.Single(s => s.Id == appTypeID); 我對此解決方案感到不滿 – 2012-04-26 17:47:58

0

你試過:

@Html.DropDownListFor(model => model.ApplicationType.Id, m => m.ApplicationType.Type, "Choose...") 

注意的第二個參數的變化。

+0

謝謝@ mirezus!不幸的是,它不起作用,因爲第二個參數需要一個,而不是lambda。 – 2012-04-26 11:31:40

+0

哦,沒錯。您通常可以將項目內聯到selectlistitem中,即:new SelectListItem {Text = m.TextToUse,Data = m.DataToUse} – mirezus 2012-05-16 17:42:40