我发现了很多这方面的文章,但我仍然不知道如何做到这一点。我正在尝试创建自己的博客引擎,我有查看创建文章(我首先使用EF和代码),现在我必须填写应该添加文章的类别数,但我想将其更改为名称为的dropdownlist类别。我的模型看起来像这样:
public class Article
{
public int ArticleID { get; set; }
[Required]
public string Title { get; set; }
[Required]
public int CategoryID { get; set; }
public DateTime Date { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
我知道我必须使用Enum(或者我认为),但我不确定如何。我不知道我发现哪个教程最适合我。
修改
感谢您的回答,但我找到了别的东西。我正在尝试这个:
这是我的模特:
public class Article
{
[Key]
public int ArticleID { get; set; }
[Display(Name = "Title")]
[StringLength(30, MinimumLength = 5)]
[Required]
public string Title { get; set; }
public DateTime Date { get; set; }
public int CategoryID { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public Category Category { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class Category
{
[Key]
public int CategoryId { get; set; }
[Required]
public string CategoryName { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
这是我创建文章的控制器:
public ActionResult Vytvorit()
{
IEnumerable<Category> categories = GetCaregories();
var view = View(new Article() { Categories = categories });
view.TempData.Add("Action", "Create");
return view;
}
private static IEnumerable<Category> GetCaregories()
{
IEnumerable<Category> categories;
using (BlogDBContext context = new BlogDBContext())
{
categories = (from one in context.Categories
orderby one.CategoryName
select one).ToList();
}
return categories;
}
private Category GetCategory(int categoryID)
{
return db.Categories.Find(categoryID);
}
//
// POST: /Clanky/Vytvorit
[HttpPost]
public ActionResult Vytvorit(Article newArticle)
{
try
{
if (newArticle.CategoryID > 0)
{
newArticle.Category = GetCategory(newArticle.CategoryID);
}
if (TryValidateModel(newArticle))
{
db.Articles.Add(newArticle);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
newArticle.Categories = GetCaregories();
var view = View(newArticle);
view.TempData.Add("Action", "Create");
return view;
}
}
catch
{
return View();
}
}
这是我观点的一部分:
@Html.DropDownListFor(model => model.CategoryID, new SelectList(Model.Categories,"CategoryID","CategoryName"))
@Html.ValidationMessageFor(model => model.CategoryID)
我有NullReferenceExeption的问题,但我不知道为什么。我可以这样做吗?对我来说看起来很容易。
答案 0 :(得分:20)
你的模特看起来很奇怪。它包含CategoryID
和Category
等属性,这些属性似乎是多余的。它还包含一个名为SelectListItem
的{{1}}集合属性。那么,这是模型还是视图模型?它看起来很混乱。让我们假设它是一个模型。在这种情况下,它更像是这样:
Categories
现在模型已经清楚了,我们可以定义一个将传递给视图的视图模型。视图模型是专门为视图设计的类。因此,根据您打算在此视图中放置的内容,您可以在此视图模型中定义它。到目前为止,你只谈到了下拉,所以让我们这样做:
public class Article
{
public int ArticleID { get; set; }
[Required]
public string Title { get; set; }
public DateTime Date { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<Category> Categories { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
然后我们有一个控制器:
public class ArticleViewModel
{
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
因此控制器使用存储库来获取模型,将其映射到视图模型(在此示例中我使用AutoMapper)并将视图模型传递给视图,该视图将负责显示它:
public class ArticlesController: Controller
{
private readonly IArticlesRepository _repository;
public ArticlesController(IArticlesRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
Article article = _repository.GetArticle();
ArticleViewModel viewModel = Mapper.Map<Article, ArticleViewModel>(article);
return View(viewModel);
}
}
答案 1 :(得分:4)
我也经历过这个,我不得不同意,起初看起来很奇怪(在我的解释中,我假设你只想选择一个类别,但是对于多重选择,过程非常相似)。
基本上您需要执行 3个步骤:
1:
您的viewmodel需要两个属性
一个将保留所选的类别ID(回发所需),另一个将包含所有可能类别的SelectList
:
public class Article
{
public int ArticleID { get; set; }
public int CategoryID { get; set; }
public SelectList Categories { get; set; }
}
2:
在将viewmodel传递给视图之前,您需要初始化SelectList
(最佳实践是在将模型传递到视图之前尽可能准备):
new SelectList(allCategories, "CategoryID", "Name", selectedCategoryID)
3:
在视图中,您需要为ListBox
属性添加CategoryID
,但使用Categories
属性也会在ListBox
中添加值:
@Html.ListBoxFor(model => model.CategoryID , Model.Categories)
多数民众赞成!在控制器的回发操作中,您将设置CategoryID。你可以从那里做任何你需要的东西来保存数据库中的东西。