无法让 DropDownList 在 .NET (C#) 中工作

Can't get DropDownList working in .NET (C#)

我对 .NET 还是很陌生,但我想我已经阅读了关于这个主题的所有内容(包括关于 SO 的类似问题,这是我尝试过的一些东西的来源) ).我觉得我已经尝试了所有可能的方法,但仍然无法正常工作。

我有一个注释 class 和一个类别 class。非常简单,每个笔记都有一个类别 属性,所以我想在我的创建视图中有一个显示类别的下拉列表。我可以获得一个列表来正确显示类别名称,仅此而已。它一直告诉我在我的 ViewData 中没有名为“类别”的 IEnumerable 确实存在,1000% 肯定是...

我的 NoteController 中的创建操作如下所示:

        // 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")

我的 Create 视图使用 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 为空,因此 CategoryId 值实际上并未从下拉列表传递到模型中。

传递给您的视图的模型需要 属性 作为 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>

好的...我想通了。

太蠢了

您用来在 ViewData 中存储 SelectList 的密钥必须与模型上 属性 的名称相同,即使您可以明确地告诉它使用不同的密钥来使用列表....

因此,即使您想对几个不同的属性使用相同的 SelectList(例如,在您的服务中以不同方式处理它们),您也必须将它冗余地传递给每个 属性 的 ViewData

因此,我没有将我的 SelectList 作为 ViewBag.Categories 传递,而是将其作为 ViewBag.CategoryId 传递,并且成功了。

我现在要去喝很多酒

如果在视图中使用 ViewModel,那么最好通过模型属性将数据 paa 到视图。无需将 Dropdownlist 的集合放入 ViewDataViewBag.

关于使用 DropdownlistSelectList 并传递到视图的详细方法,我会参考我发布的答案: