2012-03-27 72 views
0

您好我正在努力找到正確的方法,因爲我目前正在做的,所以我想我會問。MVC3 ViewModel與SelectList的映射

這裏是我的簡化代碼:

的實體嵌套基於使用他們EF CodeFirst和視圖模型類型被映射與AutoMapper。

由於下拉列表映射到model.CourseId並顯示我的課程數據,即CourseId = 2,CourseList = Null,但也具有[Required]屬性,因此發佈表單時ModelState無效CourseId是必需的,但我也需要一個相關的錯誤信息。

然後我認爲在我的Create GET & POST操作中,視圖應該只有CourseId,但我仍然需要將其顯示爲下拉列表並填充它,但我不確定如何正確執行此操作。

我可能也不會理解這應該如何正確使用,如果我甚至需要課程名稱,即因爲課程已經存在於數據庫中我只想要一個外鍵,它仍然會讓我顯示選定的課程。

我還打算將我的控制器操作中的所有映射和數據設置分解爲單獨的服務層,但目前它的一個小原型。

// Entities 
public class Recipe { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Course Course { get; set; } 
} 

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

// View Model 
public class RecipeCreateViewModel { 
    // Recipe properties 
    public int Id { get; set; } 
    public string Name { get; set; } 

    // Course properties, as primitives via AutoMapper 
    public int CourseId { get; set; } 
    public string CourseName { get; set; } 

    // For a drop down list of courses 
    [Required(ErrorMessage = "Please select a Course.")] 
    public SelectList CourseList { get; set; } 
} 

// Part of my View 
@model EatRateShare.WebUI.ViewModels.RecipeCreateViewModel 
... 
<div class="editor-label"> 
     Course 
    </div> 
    <div class="editor-field"> 
     @* The first param for DropDownListFor will make sure the relevant property is selected *@ 
     @Html.DropDownListFor(model => model.CourseId, Model.CourseList, "Choose...") 
     @Html.ValidationMessageFor(model => model.CourseId) 
    </div> 
    ... 


    // Controller actions 

    public ActionResult Create() { 
     // map the Recipe to its View Model 
     var recipeCreateViewModel = Mapper.Map<Recipe, RecipeCreateViewModel>(new Recipe()); 
     recipeCreateViewModel.CourseList = new SelectList(courseRepository.All, "Id", "Name"); 
     return View(recipeCreateViewModel); 
    } 

    [HttpPost] 
    public ActionResult Create(RecipeCreateViewModel recipe) { 
     if (ModelState.IsValid) { 
      var recipeEntity = Mapper.Map<RecipeCreateViewModel, Recipe>(recipe); 
      recipeRepository.InsertOrUpdate(recipeEntity); 
      recipeRepository.Save(); 
      return RedirectToAction("Index"); 
     } else { 
      recipe.CourseList = new SelectList(courseRepository.All, "Id", "Name"); 
      return View(recipe); 
     } 
    } 
+0

如果CourseId是必需屬性,則將'[Required]'屬性放在該列表上,而不是列表中......但由於它不可空,所以您可能甚至不需要該屬性。從列表中刪除它。 – 2012-03-27 21:22:50

+0

通過簡化事情我做了一些讓人困惑的事情.. CourseId在實體模型上有一個[Required]屬性,用於通過EFCodeFirst在sql compact數據庫中使其成爲必需字段。我可能犯了一個錯誤,認爲它會將其轉移到我的視圖模型中,因爲以前我直接使用這些實體。我從我的CourseList屬性中刪除了Required屬性,這肯定是一個錯誤。 – Pricey 2012-03-27 21:35:14

+0

由於目前還沒有答案,我會在此處更新源代碼併發布確切的錯誤消息。 – 2012-03-27 21:40:09

回答

1

我通過下面的方法解決了我的特殊問題。

 [Required(ErrorMessage = "Please select a Course.")] 
    public int CourseId { get; set; } 
    // public string CourseName { get; set; } 
    public SelectList CourseList { get; set; } 

視圖將使用DropDownListFor幫手映射下拉到我的CourseId,這一切我真的需要。

關於AutoMapper的另一個問題,以及它爲什麼沒有映射回POST Create操作中的Recipe實體。

我可能首先需要找到一種方法在「CourseName」屬性中存儲相關的課程名稱。