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

I’m still pretty new to .NET, but I think I’ve read everything there is to read on this subject (including similar questions on SO, which is where I got some of the things I’ve tried). I feel like I’ve tried everything possible and I still can’t get it to work.

I have a Note class and a Category class. Pretty straightforward, each note has a Category property, so I want to have a dropdown list in my Create view that displays categories. I can get a list to display the category names correctly, but that’s it. It keeps telling me there’s no IEnumerable in my ViewData called “Categories” when there definitely, 1000% for sure is…

The Create action in my NoteController looks like this:

        // 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();
        }

And I’ve tried a few variations in the view:

@Html.DropDownListFor(e=>e.CategoryId , (IEnumerable<SelectListItem>) ViewData["Categories"])
@Html.DropDownList("Categories", "Select a Category")

My Create view uses a NoteCreate model, which has this:

public class NoteCreate {
    ...
    [Display(Name = "Category")]
    [Required]
    public string CategoryId { get; set; }

And my NoteService has a CreateNote method like so:

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;
            }
        }

I figured I have to turn the ID into a string for the sake of the dropdown list (because SelectListItem’s Value and Text are strings), which is why I parse it back into an int here

I tried attaching the list to the ViewBag instead, and I’ve tried variations of both DropDownListFor and DropDownList

One of those combinations resulted in a dropdown list actually showing, and I don’t remember what it was, but selecting an item resulted in a null being passed to the NoteCreate method (model.CategoryId)

Can anyone help me, and potentially many others who will struggle with this in the future because the documentation is so terrible?

UPDATE:

My controller has been refactored to:

        // 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();
        }

and my view has been refactored to:

@Html.DropDownList("Categories", ViewBag.Categories as SelectList, new { @class = "form-control" })

This is closer, as I can now load the view and see the Category names in the dropdown. However, when I save, model.CategoryId in my CreateNote method is null, so the CategoryId value isn’t actually being passed from the dropdown into the model.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

If ViewModel is used in the view then its better to paa the data through model properties to the view. No need to put the collection for Dropdownlist in ViewData or ViewBag.

For the detail way of using Dropdownlist through SelectList and pass to the view through, I would refer an answer I had posted:

MVC C# Dropdown list Showing System.Web.SelectListItem on the model and can not blind to controller

Method 2

The model passed to your view needs a property for CategoryId.

Your Html Helper is looking for CategoryId here:

@Html.DropDownListFor(e=>e.CategoryId

Method 3

Ok… I figured it out.

It’s so stupid.

The key you use to store the SelectList in your ViewData HAS to be the same as the name of the property on the model, even though you can explicitly tell it to use the list using a different key….

So even if you wanted to use the same SelectList for a few different properties (but process them differently in your service, say), you’d have to pass it to the ViewData redundantly for each property

So instead of passing my SelectList through as ViewBag.Categories, I passed it in as ViewBag.CategoryId, and that worked.

I’m going to go drink a lot of alcohol now.

Method 4

In Controller

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;

View

<div class="col-md-10">
   @Html.DropDownList("Categories", ViewBag.Category_ as List<SelectListItem>, new { @class = "form-control" })
</div>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x