问题描述
我对.NET还是很陌生,但是我想我已经读完了有关该主题的所有内容(包括关于SO的类似问题,这是我尝试过的东西)。我觉得我已经尝试了所有可能的方法,但仍然无法正常工作。
我有一个Note类和一个Category类。非常简单,每个注释都有一个Category属性,因此我想在显示类别的Create视图中有一个下拉列表。我可以得到一个列表,以正确显示类别名称,仅此而已。它一直告诉我,当出现肯定的时候,我的ViewData中没有IEnumerable,叫做“ Categories”,肯定是1000%...
NoteController中的Create动作如下:
// GET: Create
public ActionResult Create()
{
SelectList items = (new CategoryService()).GetCategories().Select(c => new SelectListItem
{
Value = c.CategoryId.ToString(),Text = c.Name
}) as SelectList;
ViewData["Categories"] = items;
return View();
}
我已经尝试了视图的一些变化:
@Html.DropDownListFor(e=>e.CategoryId,(IEnumerable<SelectListItem>) ViewData["Categories"])
@Html.DropDownList("Categories","Select a Category")
“我的创建”视图使用一个具有以下内容的NoteCreate模型:
public class NoteCreate {
...
[display(Name = "Category")]
[required]
public string CategoryId { get; set; }
我的NoteService有一个CreateNote方法,如下所示:
public bool CreateNote(NoteCreate model)
{
using (var ctx = new ApplicationDbContext())
{
bool isValid = int.TryParse(model.CategoryId,out int id);
if (!isValid)
{
id = 0;
}
var entity =
new Note()
{
OwnerId = _userId,Title = model.Title,Content = model.Content,CreatedUtc = DateTimeOffset.Now,Status = model.Status,CategoryId = id
};
ctx.Notes.Add(entity);
return ctx.SaveChanges() == 1;
}
}
我认为我必须为了下拉列表而将ID转换为字符串(因为SelectListItem的Value和Text是字符串),这就是为什么我在这里将其解析为int的原因
我尝试将列表附加到ViewBag,并且尝试了DropDownListFor和DropDownList的变体
这些组合之一导致一个下拉列表实际显示,我不记得它是什么,但是选择一个项目会导致将null传递给NoteCreate方法(model.CategoryId)
有人可以帮助我吗,可能还有很多其他人会因为文档如此糟糕而在将来为此苦苦挣扎?
更新:
我的控制器已重构为:
// GET: Create
public ActionResult Create()
{
List<SelectListItem> li = new List<SelectListItem>();
List<Category> Categories = (new CategoryService()).GetCategories().ToList();
var query = from c in Categories
select new SelectListItem()
{
Value = c.CategoryId.ToString(),Text = c.Name
};
li = query.ToList();
ViewBag.Categories = li;
return View();
}
我的观点已经重构为:
@Html.DropDownList("Categories",ViewBag.Categories as SelectList,new { @class = "form-control" })
这更近了,因为我现在可以加载视图并在下拉列表中查看类别名称。但是,当我保存时,CreateNote方法中的model.CategoryId为null,因此实际上并没有将CategoryId值从下拉列表传递到模型中。
解决方法
如果在视图中使用ViewModel
,则最好通过模型属性将数据分配到视图。无需将Dropdownlist
的集合放入ViewData
或ViewBag
中。
有关使用Dropdownlist
到SelectList
并传递到视图的详细方法,我将引用我发布的答案:
,MVC C# Dropdown list Showing System.Web.SelectListItem on the model and can not blind to controller
传递给您的视图的模型需要一个CategoryId属性。
您的HTML帮助器在此处查找CategoryId:
@Html.DropDownListFor(e=>e.CategoryId
,
在控制器中
List<SelectListItem> li = new List<SelectListItem>();
var query = from of in your_context.Categories
select new SelectListItem()
{
Value = of.CategoryId.ToString(),Text = of.Name
};
li = query.ToList();
ViewBag.Category_ = li;
查看
<div class="col-md-10">
@Html.DropDownList("Categories",ViewBag.Category_ as List<SelectListItem>,new { @class = "form-control" })
</div>
,
好吧...我想通了。
太蠢了。
用于将SelectList存储在ViewData HAS中的键要与模型上属性的名称相同,即使您可以使用其他键明确告诉它使用列表也是如此。 >
因此,即使您要为几个不同的属性使用相同的SelectList(例如,在服务中对它们进行不同的处理),对于每个属性,也必须将其冗余地传递给ViewData
所以我没有将我的SelectList作为ViewBag.Categories传递给我,而是将其作为ViewBag.CategoryId传递给了我,
我现在要去喝很多酒。