0

我想添加一个带有类别的帖子,我的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请求添加类别?

4

1 回答 1

0

要将集合用于下拉列表,它必须是 type 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具有属性Id并且Name...

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

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

在旁注中,我建议您使用模型传递给您的(强类型)视图,而不是使用ViewData/ ViewBag。它在你要重构某些东西的那一天为你省去了很多麻烦,它还为你提供了很好的工具帮助(智能感知)。

于 2013-02-10T21:47:39.887 回答