使用Entity Framework填充下拉列表并向db添加新行

时间:2013-02-10 21:14:45

标签: asp.net-mvc-3 entity-framework razor

我想添加一个包含类别的帖子,Add中的BlogController操作是这样的:

private readonly IBlogPostRepository _blogPostRepository;
private readonly ICategoryRepository _categoryRepository;

public BlogController()
        {
            _blogPostRepository = new BlogPostRepository(new SiteContext());
            _categoryRepository = new CategoryRepository(new SiteContext());
        }


        public BlogController(IBlogPostRepository blogPostRepository, ICategoryRepository      categoryRepository)
        {
            _blogPostRepository = blogPostRepository;
            _categoryRepository = categoryRepository;
        }

        public ActionResult Add()
        {
            ViewData["categoryList"] = _categoryRepository.GetAllCategory();
            return View("Add");
        }

        [HttpPost]
        public ActionResult Add(BlogPost blogPost)
        {
            if (ModelState.IsValid)
            {
                blogPost.PublishDate = DateTime.Now;

                _blogPostRepository.AddPost(blogPost);
                _blogPostRepository.Save();
                return RedirectToAction("Add");
            }
            return new HttpNotFoundResult("An Error Accoured while requesting your order!");
        }

我的第一个问题是,为什么我无法在剃刀中将类别列表投射到SelectList以通过DropDownList选择类别?我在视图中的代码是这样的:

    <div>
        @Html.LabelFor(b => b.Category)
        @Html.DropDownList("Category", ViewData["categoryList"] as SelectList)
        @Html.ValidationMessageFor(b => b.Category)
    </div>

我的第二个问题是:如何使用Add请求在POST操作中添加类别?

1 个答案:

答案 0 :(得分:0)

要为下拉列表使用集合,它必须是IEnumerable<SelectListItem>类型,SelectList。您无法获取任意对象集合,只需将其转换为SelectList

我想使用扩展方法创建IEnumerable<SelectListItem>,请查看:

public static class SelectListExtensions
{
    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> source)
    {
        return ToSelectList(source, null);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> source, string defaultOption)
    {
        return ToSelectList(source, value => value, value => value.ToString(), null);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T, TDataValue>(
        this IEnumerable<T> source,
        Func<T, TDataValue> dataValueSelector,
        Func<T, string> dataTextSelector)
    {
        return ToSelectList(source, (value, index) => dataValueSelector(value), dataTextSelector, null);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T, TDataValue>(
        this IEnumerable<T> source,
        Func<T, int, TDataValue> dataValueSelector,
        Func<T, string> dataTextSelector)
    {
        return ToSelectList(source, dataValueSelector, dataTextSelector, null);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T, TDataValue>(
        this IEnumerable<T> source,
        Func<T, TDataValue> dataValueSelector,
        Func<T, string> dataTextSelector,
        string defaultOption)
    {
        return ToSelectList(source, (value, index) => dataValueSelector(value), dataTextSelector, defaultOption);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T, TDataValue>(
        this IEnumerable<T> source,
        Func<T, int, TDataValue> dataValueSelector,
        Func<T, string> dataTextSelector,
        string defaultOption)
    {
        var list = source.Select((item, index) => new SelectListItem
        {
            Value = dataValueSelector(item, index).ToString(),
            Text = dataTextSelector(item),
        }).ToList();

        if (defaultOption == null) return list;

        list.Insert(0, new SelectListItem { Text = defaultOption, Value = "-1" });

        return list;
    }
}

然后,您可以在控制器中使用此扩展方法:

public ActionResult Add()
{
    ViewData["categoryList"] = _categoryRepository.GetAllCategory()
        .ToSelectList(c => c.Id, c => c.Name);

    return View("Add");
}

假设您的Category具有属性IdName ...

然后在您的视图中使用它:

@Html.DropDownList("Category", ViewData["categoryList"] as IEnumerable<SelectListItem>)

另外,我建议您使用模型传递到(强类型)视图,而不是使用ViewData / ViewBag。它会在您重构某些东西时为您节省很多麻烦,它也为您提供了良好的工具帮助(intellisense)。