我想添加一个包含类别的帖子,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
操作中添加类别?
答案 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
具有属性Id
和Name
...
然后在您的视图中使用它:
@Html.DropDownList("Category", ViewData["categoryList"] as IEnumerable<SelectListItem>)
另外,我建议您使用模型传递到(强类型)视图,而不是使用ViewData
/ ViewBag
。它会在您重构某些东西时为您节省很多麻烦,它也为您提供了良好的工具帮助(intellisense)。