2012-03-27 4 views
0

こんにちは、現在私が行っていることに対して正しいアプローチを見つけるのに苦労しています。MVC3でSelectListを使用してViewModelをマッピングする

は、ここに私の簡素化コードされています

実体がネストされているEF CodeFirstとのViewModelでそれらを使用することに基づいて種類がAutoMapperにマップされています。

フォームをポストすると、ドロップダウンリストがmodel.CourseIdにマッピングされ、CourseId = 2、CourseList = Nullであるだけでなく、[必須]属性を持つために実際にのみ表示されるため、ModelStateは無効ですCourseIdは必須ですが、関連するエラーメッセージも必要でした。

私は、Create GET & POSTアクションでは、おそらくCourseIdだけが表示されるはずだと思っていましたが、まだドロップダウンとして表示する必要があり、それを正しく入力する方法がわかりませんでした。

私はこれが正しく使用されるべきか、またCourseNameが必要な場合、つまりコースがすでにデータベースに存在しているので理解できないかもしれません。私は選択したコース。

コントローラのアクションでこのマッピングとデータの設定をすべて別のサービスレイヤに分割する予定ですが、現時点では小さなプロトタイプです。

// 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プロパティの場合、Listにはなく[Required]属性を配置します。しかし、nullableではないので、それは必要ないかもしれません。リストから削除します。 –

+0

物事を簡素化することによって、Iiveはわずかに混乱させました。CourseIdにはエンティティモデルに[必須]属性があり、EFCodeFirst経由でSQLコンパクトデータベースで必須フィールドにするために使用されます。以前はエンティティを直接使用していたので、それをビューモデルに転送すると誤って思ったかもしれません。 CourseListプロパティからRequired属性を削除しましたが、それは間違いでした。 – Pricey

+0

まだ回答がありませんので、私はこれでソースを更新し、正確なエラーメッセージを投稿します。 –

答えて

1

以下のようにして、私の問題を解決しました。

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

ビューには、私のCourseIdにドロップダウンをマッピングするためにDropDownListForヘルパーを使用すると、それは私が本当に必要なすべてです。

AutoMapperの別の問題が発生し、なぜPOST作成アクションのレシピエンティティにマッピングされていないのでしょうか。

"CourseName"プロパティに関連するコース名を格納する方法を最初に見つけ出す必要があります。

関連する問題