在MVC3中使用SelectList映射ViewModel

时间:2012-03-27 21:03:06

标签: c# asp.net-mvc-3

嗨,我正努力在SO上找到正确的方法,因为我现在正在做的事情,所以我想我会问。

这是我的简化代码:

实体是嵌套类型,基于它们与EF CodeFirst一起使用,ViewModel与AutoMapper一起映射。

发布表单时,ModelState无效,因为dropdownlist被映射到model.CourseId并显示我的课程数据..即CourseId = 2,CourseList = Null,但也有[Required]属性,实际上只有CourseId是必需的,但我还需要一个相关的错误信息。

然后我认为在我的创建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);
        }
    }

1 个答案:

答案 0 :(得分: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”属性中。